如何将NextAuth获取的Google登录access_token发送至自定义后端并验证?
把Google Access Token发送到自定义后端并验证
一、前端发送Token到后端
根据业务场景选择以下两种方式:
1. 客户端请求后端API时携带Token
在Next.js客户端组件中,通过useSession钩子获取会话中的access_token,请求后端时将其放在请求头里:
import { useSession } from "next-auth/react"; import axios from "axios"; const SyncBackendComponent = () => { const { data: session } = useSession(); const syncWithBackend = async () => { if (!session?.access_token) return; try { const response = await axios.post( "https://your-custom-backend.com/api/auth/sync-user", { userEmail: session.user?.email, userName: session.user?.name }, { headers: { Authorization: `Bearer ${session.access_token}` } } ); console.log("后端同步成功:", response.data); } catch (err) { console.error("后端同步失败:", err); } }; return <button onClick={syncWithBackend}>同步到后端</button>; }; export default SyncBackendComponent;
2. 登录完成后自动发送Token
如果需要用户登录成功后立即同步到后端,修改[...nextauth].ts的signIn回调:
import NextAuth from "next-auth"; import GoogleProvider from "next-auth/providers/google"; import axios from "axios"; const handler = NextAuth({ providers: [ GoogleProvider({ clientId: process.env.GOOGLE_CLIENT_ID as string, clientSecret: process.env.GOOGLE_CLIENT_SECRET as string, }), ], secret: process.env.JWT_SECRET, callbacks: { async jwt({ token, account }: any) { if (account) { token.access_token = account.access_token; } return token; }, async session({ session, token }: any) { if (session) { session.access_token = token.access_token; } return session; }, // 登录成功后自动同步到后端 async signIn({ account, profile }: any) { if (!account?.access_token) return true; try { await axios.post("https://your-custom-backend.com/api/auth/verify-google-token", { access_token: account.access_token, userInfo: { email: profile?.email, name: profile?.name, avatar: profile?.picture } }); return true; } catch (err) { console.error("后端同步失败:", err); return false; // 同步失败则阻止登录 } } }, }); export { handler as GET, handler as POST };
二、后端验证Google Access Token
提供两种验证方式,推荐使用官方库保证安全性:
1. 调用Google Tokeninfo端点验证
无需额外依赖,直接请求Google官方接口:
// Express后端示例 const express = require("express"); const app = express(); app.use(express.json()); app.post("/api/auth/verify-google-token", async (req, res) => { const { access_token } = req.body; try { const verifyRes = await fetch(`https://oauth2.googleapis.com/tokeninfo?access_token=${access_token}`); const tokenInfo = await verifyRes.json(); // 验证token有效性:检查是否有错误,以及受众是否匹配你的Client ID if (tokenInfo.error || tokenInfo.aud !== process.env.GOOGLE_CLIENT_ID) { return res.status(401).json({ msg: "无效的Access Token" }); } // 验证成功,处理业务逻辑:创建/更新本地用户 // await UserModel.findOneAndUpdate( // { googleId: tokenInfo.sub }, // { email: tokenInfo.email, name: tokenInfo.name }, // { upsert: true } // ); res.status(200).json({ msg: "Token验证成功", user: { email: tokenInfo.email } }); } catch (err) { res.status(500).json({ msg: "验证失败" }); } }); app.listen(3001, () => console.log("后端服务启动"));
2. 使用Google官方库验证
安装google-auth-library后实现更严谨的验证:
npm install google-auth-library
const { OAuth2Client } = require("google-auth-library"); const express = require("express"); const app = express(); app.use(express.json()); const client = new OAuth2Client(process.env.GOOGLE_CLIENT_ID); app.post("/api/auth/verify-google-token", async (req, res) => { const { access_token } = req.body; try { // 验证Access Token const tokenInfo = await client.getTokenInfo(access_token); // 检查受众是否匹配 if (tokenInfo.aud !== process.env.GOOGLE_CLIENT_ID) { return res.status(401).json({ msg: "无效的Token受众" }); } // 处理业务逻辑:同步用户数据到本地数据库 // const user = await UserModel.upsert({ // googleId: tokenInfo.sub, // email: tokenInfo.email, // name: tokenInfo.name // }); res.status(200).json({ msg: "验证成功", user: { email: tokenInfo.email } }); } catch (err) { console.error("验证错误:", err); res.status(401).json({ msg: "Token无效或已过期" }); } }); app.listen(3001, () => console.log("后端服务启动"));
注意事项
- 后端必须配置正确的
GOOGLE_CLIENT_ID,验证时要检查token的aud字段是否匹配,防止伪造token。 - Google Access Token有效期通常为1小时,验证成功后建议后端生成自己的会话token返回给前端,后续用自定义token请求API。
- 所有验证逻辑必须在后端执行,避免前端篡改数据。
内容的提问来源于stack exchange,提问作者RRR uzumaki
相关产品推荐
相关产品推荐

