- RLS: profiles 재귀 참조 → app_metadata 기반으로 교체 - auth callback: 쿠키를 response에 직접 설정 (세션 유지) - middleware: Supabase 세션 갱신 추가 - layout: requireAdmin() 사용으로 통합 (중복 제거) - admin-guard: app_metadata.role 기반 (JWT, DB 쿼리 불필요) - debug 라우트 제거 - config.toml: localhost:3000/3001 redirect URL 추가
37 lines
1.2 KiB
TypeScript
37 lines
1.2 KiB
TypeScript
// apps/admin/src/middleware.ts
|
|
// Supabase 세션 갱신 미들웨어 — 모든 요청에서 쿠키 기반 세션을 갱신
|
|
|
|
import { NextResponse, type NextRequest } from 'next/server'
|
|
import { createServerClient, type CookieOptions } from '@supabase/ssr'
|
|
|
|
export async function middleware(request: NextRequest): Promise<NextResponse> {
|
|
const response = NextResponse.next({ request: { headers: request.headers } })
|
|
|
|
const url = process.env.NEXT_PUBLIC_SUPABASE_URL
|
|
const key = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
|
|
|
|
if (!url || !key) return response
|
|
|
|
const supabase = createServerClient(url, key, {
|
|
cookies: {
|
|
getAll() {
|
|
return request.cookies.getAll()
|
|
},
|
|
setAll(cookiesToSet: Array<{ name: string; value: string; options: CookieOptions }>) {
|
|
cookiesToSet.forEach(({ name, value, options }) => {
|
|
request.cookies.set({ name, value, ...options })
|
|
response.cookies.set({ name, value, ...options })
|
|
})
|
|
},
|
|
},
|
|
})
|
|
|
|
// 세션 갱신 (토큰 리프레시)
|
|
await supabase.auth.getUser()
|
|
|
|
return response
|
|
}
|
|
|
|
export const config = {
|
|
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
|
|
}
|