d3ro-voice/server/supabase/functions/_shared/auth.ts
2026-08-29 18:33:45 +09:00

46 lines
1.4 KiB
TypeScript

// server/supabase/functions/_shared/auth.ts
// JWT 검증 + 인증된 유저 반환
import { createClient, type User } from 'https://esm.sh/@supabase/supabase-js@2.39.7'
export interface AuthError {
status: number
message: string
}
export function authErrorResponse(error: AuthError, corsHeaders: Record<string, string>): Response {
return new Response(JSON.stringify({ error: error.message }), {
status: error.status,
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
}
/**
* Authorization 헤더에서 JWT를 추출하여 유저를 검증한다.
* 실패 시 예외 대신 AuthError 객체를 throw.
*/
export async function requireUser(req: Request): Promise<User> {
const authHeader = req.headers.get('Authorization')
if (!authHeader) {
// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw { status: 401, message: 'Missing Authorization header' } as AuthError
}
const supabaseUrl = Deno.env.get('SUPABASE_URL') ?? ''
const supabaseAnonKey = Deno.env.get('SUPABASE_ANON_KEY') ?? ''
const supabase = createClient(supabaseUrl, supabaseAnonKey, {
global: { headers: { Authorization: authHeader } }
})
const {
data: { user },
error
} = await supabase.auth.getUser()
if (error || !user) {
// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw { status: 401, message: error?.message ?? 'Invalid auth token' } as AuthError
}
return user
}