You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 08:06:03