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

如何解决Next.js 13.4中Next Auth谷歌登录的Access Denied错误

解决Next.js 13.4 + NextAuth谷歌登录AccessDenied及MongoDB连接错误

核心问题分析

  1. TypeError: Cannot read properties of undefined (reading 'catch'):console.log()执行后返回undefined,你尝试对其链式调用.catch(),直接导致报错。
  2. AccessDenied错误:数据库连接异常会中断登录流程,同时需检查谷歌OAuth控制台的回调URL配置是否合规。
  3. 数据库连接状态未更新:connectToDB函数未在连接成功后设置isConnected = true,可能引发重复连接或状态判断失效。
  4. Session回调数据丢失:用.then()包裹User.findOne后,sessionUser被赋值为undefined,后续访问_id必然报错。

修复代码

1. 修复database.js

import mongoose from "mongoose";

let isConnected = false;
export const connectToDB = async () => {
  mongoose.set("strictQuery", true);
  if (isConnected) {
    console.log("MongoDB已连接");
    return;
  }
  try {
    const connection = await mongoose.connect(process.env.MONGODB_URI);
    isConnected = true; // 连接成功后更新状态
    console.log("MongoDB连接成功:", connection.connection.host);
  } catch (error) {
    console.error("MongoDB连接失败:", error);
    throw error; // 抛出错误让上层流程处理
  }
};

2. 修复[...nextauth]/route.js

import User from "@/models/user";
import { connectToDB } from "@/utils/database";
import NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";

const authHandler = NextAuth({
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
    }),
  ],
  callbacks: {
    async signIn({ profile }) {
      try {
        await connectToDB();
        console.log(`已连接数据库: ${process.env.MONGODB_URI}`);
        
        const userExists = await User.findOne({ email: profile.email });
        if (!userExists) {
          await User.create({
            email: profile.email,
            username: profile.name.replace(" ", "").toLowerCase(),
            image: profile.image,
          });
          console.log("新用户创建成功");
        }
        return true;
      } catch (error) {
        console.error("登录流程出错:", error);
        return false;
      }
    },

    async session({ session }) {
      try {
        await connectToDB();
        // 直接await查询结果,避免用.then()包裹导致数据丢失
        const sessionUser = await User.findOne({ email: session.user.email });
        if (sessionUser) {
          session.user.id = sessionUser._id.toString();
        }
        return session;
      } catch (err) {
        console.error("Session回调出错:", err);
        return session; // 出错时返回原始session,避免登录流程中断
      }
    },
  },
  secret: process.env.NEXTAUTH_SECRET,
});

export { authHandler as GET, authHandler as POST };

额外检查项

  • 谷歌OAuth回调URL:登录谷歌云控制台,找到你的OAuth客户端,确保已添加http://localhost:3000/api/auth/callback/google到「已授权的重定向URI」列表。
  • 环境变量有效性:重启开发服务器,确认.env文件中的GOOGLE_ID、GOOGLE_SECRET、MONGODB_URI等变量已正确加载。
  • MongoDB网络权限:检查MongoDB Atlas的IP白名单,确保当前开发环境的IP地址已被允许访问数据库集群。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 03:27:43