diff --git a/src/app/api/auth/[...nextauth]/route.ts b/src/app/api/auth/[...nextauth]/route.ts index dffed736..330354da 100644 --- a/src/app/api/auth/[...nextauth]/route.ts +++ b/src/app/api/auth/[...nextauth]/route.ts @@ -1,53 +1,2 @@ -/** - * NextAuth v4 配置(route 端) - * - * 极简模式:参考 `auth.js` 官方示例的**精神**(不做任何持久化),但保留 v4 语法: - * - 客户端点击登录按钮 → `AuthPlatform.googleSignIn()` / `AuthPlatform.facebookSignIn()` - * - NextAuth 重定向到 Google / Facebook OAuth - * - OAuth 回调 → NextAuth 写 `next-auth.session-token` (httpOnly) cookie - * - 重定向到 callbackUrl (默认 /chat) - * - 业务 token 持久化(unstorage / 后端 / 自定义 cookie)**全部不在本轮 scope** - * - * v4 模式:`NextAuth(options)` 返回单个 handler 函数(v5 才返回 `{ handlers, signIn, signOut, auth }`)。 - * 通过 `export { handler as GET, handler as POST }` 暴露给 Next.js 路由。 - */ -import NextAuth from "next-auth"; -import Google from "next-auth/providers/google"; -import Facebook from "next-auth/providers/facebook"; - -const handler = NextAuth({ - providers: [ - Google({ - clientId: process.env.AUTH_GOOGLE_ID ?? "", - clientSecret: process.env.AUTH_GOOGLE_SECRET ?? "", - }), - Facebook({ - clientId: process.env.AUTH_FACEBOOK_ID ?? "", - clientSecret: process.env.AUTH_FACEBOOK_SECRET ?? "", - }), - ], - // 把 OAuth provider 的 token 塞进 NextAuth session,供前端取用: - // - Google: account.id_token → 调后端 /api/auth/google-login 换业务 token - // - Facebook: account.access_token → 调后端 /api/auth/facebook-login - // 仅在**首次 sign-in** 时把 `account` 注入到 JWT;后续请求 account=undefined - // (由 NextAuth 控制),所以下面的 `if (account)` 守卫是必要的。 - callbacks: { - async jwt({ token, account }) { - if (account) { - token.provider = account.provider; - token.idToken = account.id_token; - token.accessToken = account.access_token; - } - return token; - }, - async session({ session, token }) { - // 暴露给 `useSession()` —— 仅 client-side 派发 sync 事件时使用,不落 localStorage - session.provider = (token.provider as "google" | "facebook" | undefined) ?? undefined; - session.idToken = (token.idToken as string | undefined) ?? undefined; - session.accessToken = (token.accessToken as string | undefined) ?? undefined; - return session; - }, - }, -}); - +import { handler } from "@/lib/auth/auth"; export { handler as GET, handler as POST }; diff --git a/src/lib/auth/auth.ts b/src/lib/auth/auth.ts new file mode 100644 index 00000000..5b74243a --- /dev/null +++ b/src/lib/auth/auth.ts @@ -0,0 +1,46 @@ +/** + * NextAuth v4 配置(单一来源) + * + * v4 模式:`NextAuth(options)` 返回单个 handler 函数。 + * route 绑定在 `src/app/api/auth/[...nextauth]/route.ts`。 + * + * 客户端通过 `src/lib/auth/{auth_platform,logout}.ts` 触发。 + */ +import NextAuth from "next-auth"; +import Google from "next-auth/providers/google"; +import Facebook from "next-auth/providers/facebook"; + +export const handler = NextAuth({ + providers: [ + Google({ + clientId: process.env.AUTH_GOOGLE_ID ?? "", + clientSecret: process.env.AUTH_GOOGLE_SECRET ?? "", + }), + Facebook({ + clientId: process.env.AUTH_FACEBOOK_ID ?? "", + clientSecret: process.env.AUTH_FACEBOOK_SECRET ?? "", + }), + ], + // 把 OAuth provider 的 token 塞进 NextAuth session,供前端取用: + // - Google: account.id_token → 调后端 /api/auth/google-login 换业务 token + // - Facebook: account.access_token → 调后端 /api/auth/facebook-login + // 仅在**首次 sign-in** 时把 `account` 注入到 JWT;后续请求 account=undefined + // (由 NextAuth 控制),所以下面的 `if (account)` 守卫是必要的。 + callbacks: { + async jwt({ token, account }) { + if (account) { + token.provider = account.provider; + token.idToken = account.id_token; + token.accessToken = account.access_token; + } + return token; + }, + async session({ session, token }) { + // 暴露给 `useSession()` —— 仅 client-side 派发 sync 事件时使用,不落 localStorage + session.provider = (token.provider as "google" | "facebook" | undefined) ?? undefined; + session.idToken = (token.idToken as string | undefined) ?? undefined; + session.accessToken = (token.accessToken as string | undefined) ?? undefined; + return session; + }, + }, +});