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

Next.js 13中NextAuth谷歌认证后获取响应对象及令牌方法

NextAuth谷歌登录后无法获取令牌及响应对象的解决方法

你在Next.js 13中使用NextAuth实现谷歌登录时,能完成登录但无法获取响应对象、控制台无输出,且需要拿到谷歌返回的令牌用于服务端验证,问题可以通过以下步骤解决:

一、修正前端会话数据的获取逻辑

你的现有代码存在两个核心问题:useSession的用法错误,且未等待异步的signIn方法完成就尝试读取数据。修改前端代码如下:

import { useSession, signIn } from "next-auth/react";

const LoginButton = () => {
  // 正确解构useSession返回的会话数据和状态
  const { data: session, status } = useSession();

  const onClick = async () => {
    console.log("触发谷歌登录");
    // 等待signIn异步操作完成,可指定回调页避免页面跳转清空日志
    const loginResult = await signIn("google", { callbackUrl: window.location.href });
    
    // 输出登录直接结果
    console.log("登录操作返回结果:", loginResult);
    // 登录完成后会话已更新,输出完整会话数据
    console.log("当前会话信息:", session);
  };

  return <button onClick={onClick}>Sign in</button>;
};

export default LoginButton;

关键说明:

  • useSession返回的是包含data(会话数据)和status(会话状态:loading/authenticated/unauthenticated)的对象,不存在response属性。
  • signIn是异步函数,必须用await等待执行完成,才能拿到实时的登录结果和更新后的会话数据。
  • 若登录后跳转页面,原页面控制台日志会被清空,可将callbackUrl设为当前页,或开启浏览器控制台的「Preserve log」选项保留日志。

二、配置NextAuth获取并传递谷歌令牌

默认情况下,NextAuth的会话数据不会包含谷歌返回的令牌,需要通过回调函数将令牌注入会话:

修改你的认证处理代码:

import NextAuth from "next-auth"
import GoogleProvider from "next-auth/providers/google";

const handler = NextAuth({
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID ?? '',
      clientSecret: process.env.GOOGLE_CLIENT_SECRET ?? ''
    }),
  ],
  callbacks: {
    // 在JWT回调中保存谷歌返回的令牌
    async jwt({ token, account }) {
      if (account) {
        token.accessToken = account.access_token;
        token.refreshToken = account.refresh_token;
        token.expiresAt = account.expires_at;
      }
      return token;
    },
    // 将令牌注入会话,让客户端/服务端可读取
    async session({ session, token }) {
      session.user.accessToken = token.accessToken;
      session.user.refreshToken = token.refreshToken;
      session.user.expiresAt = token.expiresAt;
      return session;
    }
  }
})

export { handler as GET, handler as POST };

获取令牌的两种场景:

  1. 客户端获取:当会话状态为authenticated时,直接从会话中读取令牌:
const { data: session, status } = useSession();

if (status === "authenticated") {
  console.log("谷歌Access Token:", session.user.accessToken);
  // 可将此令牌发送到你的服务端进行验证
}
  1. 服务端获取:在服务端路由中通过getServerSession直接读取会话中的令牌,无需客户端传递:
// app/api/verify-token/route.js
import { getServerSession } from "next-auth/next";
import { handler as authOptions } from "../auth/[...nextauth]/route";

export async function GET(request) {
  const session = await getServerSession(authOptions);
  
  if (session) {
    const googleToken = session.user.accessToken;
    // 在此调用谷歌验证接口,或传递给你的后端服务完成身份校验
    console.log("服务端拿到的谷歌令牌:", googleToken);
    return new Response(JSON.stringify({ valid: true }), { status: 200 });
  } else {
    return new Response(JSON.stringify({ valid: false }), { status: 401 });
  }
}

内容的提问来源于stack exchange,提问作者Sahil Singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 21:35:13