diff options
| author | joonhoekim <26rote@gmail.com> | 2025-03-25 15:55:45 +0900 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-03-25 15:55:45 +0900 |
| commit | 1a2241c40e10193c5ff7008a7b7b36cc1d855d96 (patch) | |
| tree | 8a5587f10ca55b162d7e3254cb088b323a34c41b /app/api/auth | |
initial commit
Diffstat (limited to 'app/api/auth')
| -rw-r--r-- | app/api/auth/[...nextauth]/route.ts | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/app/api/auth/[...nextauth]/route.ts b/app/api/auth/[...nextauth]/route.ts new file mode 100644 index 00000000..609a63d7 --- /dev/null +++ b/app/api/auth/[...nextauth]/route.ts @@ -0,0 +1,111 @@ +// (1) next-auth에서 필요한 타입들을 import +import NextAuth, { + NextAuthOptions, // authOptions에 쓸 타입 + Session, + User +} from 'next-auth' +import { JWT } from "next-auth/jwt" + +import CredentialsProvider from 'next-auth/providers/credentials' + +import { verifyOtp } from '@/lib/users/verifyOtp' + +// 1) 모듈 보강 선언 +declare module "next-auth" { + /** + * Session 객체를 확장 + */ + interface Session { + user: { + /** 우리가 필요로 하는 user id */ + id: string + + // 기본적으로 NextAuth가 제공하는 name/email/image 필드 + name?: string | null + email?: string | null + image?: string | null + companyId?: number | null + domain?: string | null + + } + } + + /** + * User 객체를 확장 + */ + interface User { + id: string + imageUrl?: string | null + companyId?: number | null + domain?: string | null + // 필요한 필드를 추가로 선언 가능 + } +} + +// (2) authOptions에 NextAuthOptions 타입 지정 +export const authOptions: NextAuthOptions = { + providers: [ + CredentialsProvider({ + name: 'Credentials', + credentials: { + email: { label: 'Email', type: 'text' }, + code: { label: 'OTP code', type: 'text' }, + }, + async authorize(credentials, req) { + const { email, code } = credentials ?? {} + + // OTP 검증 + const user = await verifyOtp(email ?? '', code ?? '') + if (!user) { + return null + } + + return { + id: String(user.id ?? email ?? "dts"), + email: user.email, + imageUrl: user.imageUrl ?? null, + name: user.name, // DB에서 가져온 실제 이름 + companyId: user.companyId, // DB에서 가져온 실제 이름 + domain: user.domain, // DB에서 가져온 실제 이름 + } + }, + }) + ], + // (3) session.strategy는 'jwt'가 되도록 선언 + // 필요하다면 as SessionStrategy 라고 명시해줄 수도 있음 + // 예) strategy: 'jwt' as SessionStrategy + session: { + strategy: 'jwt', + }, + callbacks: { + // (4) 콜백에서 token, user, session 등의 타입을 좀 더 명시해주고 싶다면 아래처럼 destructuring에 제네릭/타입 지정 + async jwt({ token, user }: { token: JWT; user?: User }) { + if (user) { + token.id = user.id + token.email = user.email + token.name = user.name + token.companyId = user.companyId + token.domain = user.domain + ; (token as any).imageUrl = (user as any).imageUrl + } + return token + }, + async session({ session, token }: { session: Session; token: JWT }) { + if (token) { + session.user = { + id: token.id as string, + email: token.email as string, + name: token.name as string, + domain: token.domain as string, + companyId: token.companyId as number, + image: (token as any).imageUrl ?? null + } + } + return session + }, + }, +} + +const handler = NextAuth(authOptions) + +export { handler as GET, handler as POST }
\ No newline at end of file |
