iT邦幫忙

2026 iThome 鐵人賽

DAY 8
0
Vibe Coding

Vibe Mode 開啟:30 天用 AI 打造網頁,邊做邊學 JavaScript系列 第 8

# Day 8 : 使用者是誰?整合 Supabase Auth 輕鬆搞定身份驗證與授權

  • 分享至 

  • xImage
  •  

到了第 8 天,我們的「AI 輔助個人財務追蹤器」已經有了資料庫 ERD 與基礎 API。但記帳軟體最核心的一點就是——隱私。我總不能讓全網際網路的人都看到我昨晚又爆買了什麼吧?

今天我們要開啟 Vibe Mode,讓 AI 幫我們在 15 分鐘內把 Supabase Auth 整合進 Next.js 專案,實現 Email/密碼登入與路由保護(Middleware Protect)!


Human vs. AI 實戰對照:安裝與初始化 Setup

1. 給 AI 的指令 (Prompt)

我們正在開發一個 Next.js 14 (App Router) + Supabase 的個人財務追蹤專案。
請幫我撰寫 Supabase Auth 的初始化程式碼:
1. 包含 Server-side 與 Client-side 的 Supabase client 建立方式 (@supabase/ssr)。
2. 提供一個登入/註冊的 React 組件 (Login Form),使用 Tailwind CSS 美化。
3. 請確保遵循 Next.js App Router 的最佳實踐。


2. AI 產出的結果 (Code Snippet)

AI 很快地幫我生成了 Client Client 的範例:

// utils/supabase/client.ts
import { createBrowserClient } from '@supabase/ssr'

export function createClient() {
  return createBrowserClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
  )
}

以及 Login Form 組件的提交邏輯:

// app/login/page.tsx
'use client'
import { useState } from 'react'
import { createClient } from '@/utils/supabase/client'

export default function LoginPage() {
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  const supabase = createClient()

  const handleSignIn = async () => {
    const { error } = await supabase.auth.signInWithPassword({ email, password })
    if (error) alert(error.message)
    else window.location.href = '/dashboard'
  }

  // ...UI JSX 略...
}


3. 修正與判斷 (Human Touch)

雖然程式碼看起來能用,但我立刻發現了幾個隱患與過時作法

  1. 路由跳轉不夠 Next.js 原生:AI 使用了 window.location.href = '/dashboard',這會導致全頁硬刷(Hard Refresh),失去了 SPA/Next.js Client-side Routing 的優勢。我將其改為 useRouter()router.push('/dashboard') 並搭配 router.refresh()
  2. 缺乏 Server Actions 整合:在 Next.js App Router 中,更推薦將身份驗證的 Form Auth 邏輯寫成 Server Actions,而不是全部暴露在 Client Component。

翻車與除錯過程 (Debug Experience)

🐛 踩坑:無窮迴圈重定向 (Infinite Redirect Loop)

在接續讓 AI 生成 middleware.ts 來保護敏感路由(例如 /dashboard)時,系統居然陷入了無限重定向的死迴圈!

AI 一開始寫的 Middleware Bug 程式碼:

// middleware.ts
import { NextResponse, type NextRequest } from 'next/server'
import { createServerClient } from '@supabase/ssr'

export async function middleware(request: NextRequest) {
  // ... Supabase 初始化 ...
  const { data: { user } } = await supabase.auth.getUser()

  // 🐛 這裡出事了!沒有檢查目前是否已經在 /login 頁面
  if (!user) {
    return NextResponse.redirect(new URL('/login', request.url))
  }
}

當使用者未登入存取任何頁面時,Middleware 會把他導向 /login;然而當瀏覽器請求 /login 時,Middleware 又觸發了一次,檢查發現依然「未登入」,於是再次導向 /login……蹦!直接炸掉。


我的引導修正

沒有選擇自己動手改,而是直接把錯誤訊息與程式碼丟回給 AI 進行「對話式除錯」:

你在 middleware.ts 寫的重定向邏輯導致了 Infinite Redirect Loop。
當未登入的使用者存取 /login 頁面時,也會觸發重新導向到 /login。
請修復這個問題,並確保:
1. 如果未登入且存取受保護路由 (如 /dashboard),導向 /login。
2. 如果「已登入」的使用者存取 /login,自動幫他導向 /dashboard。


最終修復後的 Middleware

import { NextResponse, type NextRequest } from 'next/server'
import { updateSession } from '@/utils/supabase/middleware'

export async function middleware(request: NextRequest) {
  const { response, user } = await updateSession(request)

  const isLoginPage = request.nextUrl.pathname.startsWith('/login')
  const isDashboardPage = request.nextUrl.pathname.startsWith('/dashboard')

  // 未登入想進 Dashboard -> 送去 Login
  if (!user && isDashboardPage) {
    return NextResponse.redirect(new URL('/login', request.url))
  }

  // 已登入還想進 Login -> 送去 Dashboard
  if (user && isLoginPage) {
    return NextResponse.redirect(new URL('/dashboard', request.url))
  }

  return response
}

export const config = {
  matcher: ['/dashboard/:path*', '/login'],
}


JavaScript / JS 概念小知識

在今天整合 Auth 的過程中,我們學到了幾個關鍵的 JS / Web 概念:

  1. Cookie vs LocalStorage 存取 Token
    傳統前端常把 JWT 存在 localStorage,但這容易遭受 XSS 攻擊,且 Server-Side Rendering (SSR) 無法在伺服器端讀取到 localStorage。Supabase @supabase/ssr 套件改用 PKCE 流水線 + HTTP-Only Cookies,讓 Server Component 與 Middleware 能直接讀取 Session,安全性大幅提升!
  2. Asynchronous Middleware Handling
    Next.js Middleware 是運行在 Edge Runtime 上,所有的 Auth 狀態檢查都是非同步(async/await)的。處理 HTTP Header 與 Response 重新轉發時,必須確保 Cookie 有正確寫回 NextResponse,否則使用者登入完重新整理又會被登出。

結語

Vibe Coding 不是盲目複製貼上,而是讓 AI 當你的超速打字員,你來當最後的架構審查官。今天順利建立了使用者驗證機制,明天 Day 9 我們將繼續推進,引導 AI 為系統加上嚴密的 Zod 資料驗證與 Try-Catch 邊界處理


上一篇
# Day 7 : Vibe Mode 開啟:打造 RESTful API —— 讓 AI 撰寫 Controller 與 Service 邏輯
下一篇
# Day 9 : 別讓防線大開!引導 AI 補足 Try-Catch、Zod 驗證與全域 Error Handling
系列文
Vibe Mode 開啟:30 天用 AI 打造網頁,邊做邊學 JavaScript9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言