第二章:Auth.js 初始化、Google Developer Console 申請與環境變數設定

理論課結束,是時候弄髒你的雙手了!在商業開發中,實作第三方登入最困難的往往不是「寫程式」,而是「跨越各大科技巨頭(如 Google, Facebook, Line)複雜又時常改版的開發者後台」。

本章節我們將不厭其煩地、一步一步帶著你闖關 Google Cloud Console。我們不僅會告訴你「怎麼做」,更會詳細解釋「為什麼要填這些資料」,確保未來 Google 介面改版時,你依然能一眼看懂核心邏輯。


🛠️ 步驟一:專案安裝與依賴包準備

首先,確保你已經有一個建置好的 Next.js 14+ (App Router) 專案。 打開你的終端機 (Terminal),在專案根目錄下執行以下指令:

# 安裝最新版的 Auth.js (目前標記為 beta 以支援最新的 App Router 特性)
npm install next-auth@beta

這會安裝核心的認證套件。值得注意的是,即使它叫做 beta,它在生產環境中已經非常穩定,並且被 Vercel 官方強烈推薦。

產生不可破解的 Auth Secret

Auth.js 需要一把「鑰匙 (Secret)」來對所有的 Session Cookie 與 JWT 進行高強度加密。如果沒有這把鑰匙,或者鑰匙太過簡單(例如 123456),駭客就可以輕易偽造登入憑證。

在終端機中輸入以下魔法指令:

npx auth secret

這支小程式會自動為你生成一組 32 bytes 的亂碼雜湊值,並且自動加到你專案根目錄的 .env.local 檔案中

打開你的 .env.local,你應該會看到類似這樣的一行:

AUTH_SECRET="Jk9z8H/yT7xM4+qR1pW2vN6bL3jX5cD8eF0gA9hI4Kk="

⚠️ 商業資安警告: 這個 AUTH_SECRET 是你網站的「護國神山」。絕對不能把 .env.local 提交到 GitHub 上 (請確保 .gitignore 有生效)。如果這串鑰匙外洩,駭客可以直接在自己的電腦上簽發具有管理員權限的 Token 登入你的系統!


🌐 步驟二:闖關 Google Cloud Console 申請憑證

這是無數新手卡關三天三夜的地方。Google 的後台設計是給全宇宙最複雜的企業用的,所以介面選項多到令人髮指。請緊跟以下步驟:

1. 建立 GCP 專案 (Google Cloud Project)

  1. 前往 Google Cloud Console 並使用你的 Google 帳號登入。
  2. 點擊左上角的專案下拉選單,點擊 「新增專案 (New Project)」
  3. 專案名稱填寫:VibeTutor-Auth-System (你可以自訂),點擊建立。
  4. 等待右上角的小鈴鐺顯示建立完成後,務必點擊選擇你剛建好的新專案

2. 設定 OAuth 同意畫面 (OAuth Consent Screen)

Google 非常重視隱私。當使用者點擊登入時,Google 必須彈出一個畫面告訴使用者:「VibeTutor 想要拿你的資料喔!你同意嗎?」我們現在就是要設計這個彈出畫面。

  1. 從左側的漢堡選單導覽至 「API 和服務 (APIs & Services)」 > 「OAuth 同意畫面 (OAuth Consent Screen)」
  2. User Type (使用者類型):請選擇 「外部 (External)」(註:內部 Internal 只適用於 Google Workspace 的企業網域內員工使用)
  3. 點擊 建立 (Create)

現在進入了詳細資料填寫頁:

  • 應用程式名稱 (App name):填入 VibeTutor 知識付費平台。這會直接顯示給終端用戶看。
  • 使用者支援電子郵件:選你自己的 Email。
  • 應用程式標誌 (App logo):(選填) 商業專案建議一定要上傳 Logo,這樣登入畫面會顯得非常專業且具有信任感。
  • 已授權網域 (Authorized domains):如果是本地開發先留空。未來正式上線時,必須填入你的正式網域 (例如 vibe-tutor.com)。
  • 開發人員聯絡資訊:填入你的 Email。

接下來的 範圍 (Scopes) 步驟: 所謂的 Scope 就是你想跟使用者討要「多少資料」。 預設我們只需要 .../auth/userinfo.email.../auth/userinfo.profile。直接點選 儲存並繼續 即可。

最後的 測試使用者 (Test users) 步驟: 在應用程式處於「測試階段 (Testing)」時,只有被加入這裡的 Email 才能登入成功! 👉 請務必把你自己,以及你客戶的 Gmail 帳號加進去。否則你等一下測試會直接報錯 Access Denied

3. 建立 OAuth 用戶端 ID 與密碼

畫面設定好了,現在我們要去拿最重要的金鑰 (Client ID & Client Secret)。

  1. 點擊左側導覽列的 「憑證 (Credentials)」
  2. 點擊畫面上方的 「+ 建立憑證 (CREATE CREDENTIALS)」,選擇 「OAuth 用戶端 ID (OAuth client ID)」
  3. 應用程式類型 (Application type):選擇 「網頁應用程式 (Web application)」
  4. 名稱填入:VibeTutor Next.js Web Client

接下來是最關鍵、最容易填錯的兩個網址設定:

【已授權的 JavaScript 來源 (Authorized JavaScript origins)】 這代表你的網站網址在哪裡。Google 只允許從這些網址發起的登入請求。

  • 請點擊「新增 URI」,填入:http://localhost:3000

【已授權的重新導向 URI (Authorized redirect URIs)】 回想第一章的流程圖,當使用者在 Google 登入成功後,Google 要把「授權碼 (Authorization Code)」寄回給你的伺服器。Google 必須知道要寄到哪個網址,否則駭客可以讓 Google 把授權碼寄到駭客的伺服器。 這就是 Callback URL。

  • 請點擊「新增 URI」,填入 Auth.js 規定的死板路徑: 👉 http://localhost:3000/api/auth/callback/google

🚨 常見除錯陷阱 (Troubleshooting)

  1. localhost 前面一定要有 http://,絕對不能寫 https:// (除非你在本地有發憑證)。
  2. 網址最後面絕對不能有斜線 /
  3. 未來當你部署到 Vercel 時,你必須回來這個畫面,把 https://vibe-tutor.com 加上去,否則正式機的登入一定會壞掉!

設定完成後,點擊「建立」。螢幕上會彈出一個視窗,顯示你的 用戶端 ID (Client ID)用戶端密碼 (Client Secret)。 請把它們複製下來。


💻 步驟三:環境變數設定與 NextAuth 核心配置

回到你的程式碼編輯器。打開 .env.local,把你剛才從 Google 拿到的雙寶貼上去:

AUTH_SECRET="Jk9z8H/yT7xM4+qR1pW2vN6bL3jX5cD8eF0gA9hI4Kk="

# Google OAuth 憑證
AUTH_GOOGLE_ID="123456789-abcde.apps.googleusercontent.com"
AUTH_GOOGLE_SECRET="GOCSPX-xxxxxx_yyyyyy_zzzzzz"

撰寫 auth.ts 核心設定檔

在 Next.js 專案的 src 目錄下(如果你沒有用 src 目錄,就是在專案根目錄下),建立一個名為 auth.ts 的檔案。這個檔案是 Auth.js v5 統一管理設定的地方。

// src/auth.ts
import NextAuth from "next-auth"
import GoogleProvider from "next-auth/providers/google"
 
export const { 
  handlers, // 處理 GET/POST 路由
  signIn,   // 登入方法
  signOut,  // 登出方法
  auth      // 取得當前 Session 狀態的萬用函式
} = NextAuth({
  // 在這裡設定所有你想要支援的第三方登入提供者
  providers: [
    GoogleProvider({
      clientId: process.env.AUTH_GOOGLE_ID,
      clientSecret: process.env.AUTH_GOOGLE_SECRET,
      // 可選:如果你希望每次登入都強制跳出選擇帳號的畫面,可以加上這行
      // authorization: { params: { prompt: "consent" } },
    }),
  ],
  // 其他進階設定 (後續章節會用到)
  // pages: { signIn: '/login' } 
})

🧠架構深度解析: 為什麼我們要建立這個 auth.ts 檔案?在 Auth.js v4 時代,設定檔都寫在 API Route 裡面,這導致在 Server Components 中很難重複使用設定。v5 版本把設定全部抽離出來,產生了 signIn, signOut, auth 這三個魔法函式,讓你可以在專案的「任何地方(不論是前端元件、後端 API、Middleware)」都能輕鬆呼叫。

建立 API Route (Route Handler)

Google 把資料回傳時,我們的 Next.js 需要有一個「端點」來接住這些資料。 請建立一個資料夾結構與檔案:src/app/api/auth/[...nextauth]/route.ts

註:[...nextauth] 是 Next.js 的 Catch-all 動態路由語法。這代表所有 /api/auth/signin, /api/auth/callback/google, /api/auth/signout 的請求,都會被這個檔案攔截處理。

在這個檔案裡寫入以下程式碼:

// src/app/api/auth/[...nextauth]/route.ts
import { handlers } from "@/auth"

// 直接把 auth.ts 裡面的 handlers 拿出來當作 GET 和 POST 路由回應
export const { GET, POST } = handlers

是的,就只有短短這兩行!你不需要寫任何 fetch、不需要寫任何 switch-case 判斷路由。Auth.js 底層已經幫你把所有的 OAuth 複雜流轉與 Token 驗證邏輯全部封裝在這兩行裡面了。


🎉 步驟四:驗收成果與除錯實戰

準備好見證奇蹟了嗎?

  1. 在終端機執行 npm run dev 啟動你的開發伺服器。
  2. 打開瀏覽器,在網址列手動輸入: 👉 http://localhost:3000/api/auth/signin

你會看到一個 Auth.js 為你自動生成的極簡登入畫面,上面有一顆白色的 「Sign in with Google」 按鈕。

深呼吸,點擊這顆按鈕。 如果你的設定完全正確:

  1. 畫面會跳轉到 Google 的帳號選擇頁面。
  2. 網址列會顯示一長串帶有 client_id=... 的 Google 授權網址。
  3. 點選你的 Google 帳號後,畫面會閃爍一下,然後跳轉回 http://localhost:3000

🚨 常見報錯與終極救援指南 (Troubleshooting)

在真實世界中,第一次設定就成功的人大概只有 10%。如果你看到了紅字錯誤,請對照以下解決方案:

錯誤 1:Error: redirect_uri_mismatch (在 Google 畫面上顯示)

  • 原因:你的 localhost 帶了奇怪的 port,或者是你剛剛在 Google Console 裡面設定的 Callback 網址打字打錯了。
  • 解法:回到 Google Cloud Console 的「憑證」頁面,仔細檢查「已授權的重新導向 URI」是否一字不差地寫著 http://localhost:3000/api/auth/callback/google。如果有修改,請等待 5 分鐘讓 Google 伺服器同步。

錯誤 2:Access Denied (403) (在 Google 畫面上顯示)

  • 原因:你的 OAuth 應用程式狀態是「測試階段 (Testing)」,而且你點擊登入的 Gmail 帳號,沒有被加入到「測試使用者 (Test users)」名單中。
  • 解法:回到 Google OAuth 同意畫面設定頁,把你的信箱加進 Test users 名單。

錯誤 3:點擊按鈕後網頁崩潰,Terminal 顯示 MissingSecret

  • 原因:你的 .env.local 裡面沒有設定 AUTH_SECRET,或者你剛剛改了環境變數但沒有重新啟動 Next.js 伺服器。
  • 解法:確認 .env.local 內容正確,並在終端機按下 Ctrl+C 終止伺服器,重新執行 npm run dev

本章總結

恭喜你!你已經完成了全宇宙最麻煩的「建立開發者憑證」關卡,並且成功在你的 Next.js 專案中掛載了 Auth.js 引擎,打通了 Google 登入。

但只有 Google 登入是不夠的。在台灣做商業開發,客戶的下一個需求絕對是:「我要 Line 登入」。 在下一章,我們將帶你探索更封閉、更具挑戰性的 Line Developers 開發者後台,並學習如何在同一個系統中,優雅地並存多種第三方登入機制。

解鎖完整教學內容

本章為付費內容。加入專案即可解鎖超過 5000 字的深度解析,包含 10 個以上神級 Prompt 與真實 Source Code 範例!