refactor(auth): extract NextAuth config to shared lib module
Move the NextAuth v4 configuration from the route handler (src/app/api/auth/[...nextauth]/route.ts) into a dedicated module (src/lib/auth/auth.ts) to establish a single source of truth. The route file now simply re-exports the handler from the shared module, keeping provider setup, JWT/session callbacks, and environment variable references in one reusable location.
This commit is contained in:
@@ -1,53 +1,2 @@
|
|||||||
/**
|
import { handler } from "@/lib/auth/auth";
|
||||||
* 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;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export { handler as GET, handler as POST };
|
export { handler as GET, handler as POST };
|
||||||
|
|||||||
@@ -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;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user