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

NextAuth session回调未执行,无法持久化Google OAuth accessToken求助

问题:NextAuth session回调未执行,无法持久化Google accessToken

问题说明

在Next.js项目中使用NextAuth结合Google OAuth实现认证,需要将Google的accessToken持久化到session中以调用Google Calendar API,但发现session()回调完全没有执行,无法完成accessToken的传递。

相关代码

[...nextauth].js

import GoogleProvider from "next-auth/providers/google"
import NextAuth from "next-auth/next"
export default NextAuth(
  {
    providers: [
      GoogleProvider({
        clientId: PROCESS.ENV.GOOGLE_CLIENT_ID',
        clientSecret: PROCESS.ENV.GOOGLE_CLIENT_SECRET,
        authorization: {
          params: {
            prompt: "consent",
            access_type: "offline",
            response_type: "code",
            scope: 'openid email profile https://www.googleapis.com/auth/calendar'
          },
        },
        callbacks: {
          async session({ session, token, user }) {
            session.user.id = token.id;
            session.accessToken = token.accessToken;
            // 从未打印
            console.log('In here');
            return session;
          },
          async jwt({ token, user, account, profile, isNewUser }) {
            console.log(token);
            if (user) {
              token.id = user.id;
            }
            if (account) {
              token.accessToken = account?.access_token;
            }
            return token;
          },
        },
      }),
    ],
    sercet: PROCESS.ENV.JWT_SECRET,
    session: {
      strategy: "jwt",
    },
  }
)

登录组件

import React, { useState } from 'react';
import {useSession, signIn, signOut} from 'next-auth/react';
import axios from 'axios';

const Login = () => {
    const x = useSession();
    const {data: session} = x
    const [calendar, setCalendar] = useState({});

    const getCalendarData = async () => {
        console.log(session.accessToken);
        console.log(x);
        const options = {  
            method: 'GET',
            headers: {
                Authorization: `Bearer ${session.accessToken}`,
            }
        };

        const url = "https://www.googleapis.com/calendar/v3/calendars/primary";
        
        let data = null
        try{
            data = await axios.get(url, options);
            setCalendar(data);
        } catch(error){
            console.log(error);
        }
        
    }

    if(session){
        return (
            <div>
                <div> Welcome, {JSON.stringify(session.user)} </div>
                <div>{JSON.stringify(calendar)}</div>
                <div><button onClick={() => signOut()}>Sign Out</button></div>
                <div><button onClick={getCalendarData}>Get Calendar Data</button></div>
            </div>
        );
    }
    else{
        return(
            <div>
                <div> You are not signed in </div>
                <div><button onClick={() =>signIn()}> Sign in</button></div>
            </div>
            )
    }
}

问题排查与修复

1. 回调配置位置错误

NextAuth的callbacks是顶层配置项,必须和providers、session同级,不能嵌套在GoogleProvider内部。你当前的写法会导致session和jwt回调完全不被NextAuth识别。

2. 拼写错误

配置中的sercet是拼写错误,正确应为secret。这个错误会导致JWT签名/验证失败,直接中断session相关流程。

3. 环境变量大小写错误

Node.js中环境变量的正确写法是process.env,而非大写的PROCESS.ENV,大写写法会导致无法读取到配置值,引发认证流程异常。

修正后的[...nextauth].js

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

export default NextAuth({
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
      authorization: {
        params: {
          prompt: "consent",
          access_type: "offline",
          response_type: "code",
          scope: 'openid email profile https://www.googleapis.com/auth/calendar'
        },
      },
    }),
  ],
  secret: process.env.JWT_SECRET,
  session: {
    strategy: "jwt",
  },
  // 回调移至顶层
  callbacks: {
    async session({ session, token }) {
      session.user.id = token.id;
      session.accessToken = token.accessToken;
      console.log('In here');
      return session;
    },
    async jwt({ token, user, account }) {
      if (user) {
        token.id = user.id;
      }
      if (account) {
        token.accessToken = account.access_token;
      }
      return token;
    },
  },
})

登录组件优化建议

  • 给useSession添加required: true配置,确保session加载完成后再渲染内容
  • 修复getCalendarData中data变量的声明错误(原代码用const后重新赋值,会报错)
const { data: session, status } = useSession({ required: true });

// 处理加载状态
if (status === "loading") {
  return <div>Loading...</div>;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 03:20:14