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

Next-Auth社交登录userId类型不匹配(String转Int)问题解决

解决Next-Auth社交登录后userId类型不匹配问题

问题本质:社交登录提供者(如Facebook)返回的用户ID是字符串类型,而你的PostgreSQL数据库中userId字段定义为Int,Prisma进行类型检查时就会抛出类型不匹配的错误。

下面是几种可行的解决办法:

方案一:在Next-Auth回调中统一转换ID类型

修改你的Next-Auth配置文件(通常是pages/api/auth/[...nextauth].js或App Router下的app/api/auth/[...nextauth]/route.js),通过jwt和session回调将用户ID转换为数字类型:

import NextAuth from "next-auth";
import FacebookProvider from "next-auth/providers/facebook";
// 导入其他需要的提供者

export const authOptions = {
  providers: [
    FacebookProvider({
      clientId: process.env.FACEBOOK_CLIENT_ID,
      clientSecret: process.env.FACEBOOK_CLIENT_SECRET,
    }),
    // 配置其他社交提供者
  ],
  callbacks: {
    async jwt({ token, user }) {
      // 用户首次登录时,将user.id转为数字
      if (user) {
        token.id = Number(user.id);
      }
      return token;
    },
    async session({ session, token }) {
      // 将转换后的ID同步到session的user对象中
      session.user.id = token.id;
      return session;
    },
  },
};

export default NextAuth(authOptions);

配置完成后,从session中获取的user.id将是数字类型,后续传递给Prisma的查询就不会触发类型错误。

方案二:在Prisma查询时手动转换ID类型

如果不想修改Next-Auth的全局配置,可以在每次执行数据库查询前,将字符串类型的userId转换为数字:

import { getServerSession } from "next-auth/next";
import { prisma } from "@/lib/prisma";
import { authOptions } from "../auth/[...nextauth]";

export default async function handler(req, res) {
  const session = await getServerSession(req, res, authOptions);
  if (!session) {
    return res.status(401).json({ error: "未授权" });
  }

  // 将字符串ID转为数字,同时校验有效性
  const userId = parseInt(session.user.id, 10);
  if (isNaN(userId)) {
    return res.status(400).json({ error: "无效的用户ID" });
  }

  const todos = await prisma.todos.findMany({
    where: { userId },
    select: { id: true, text: true, done: true },
  });

  res.status(200).json(todos);
}

这种方式适合临时修复,但需要在所有涉及userId的查询中重复处理,维护成本较高。

方案三:调整数据库字段类型(备选)

如果项目处于早期阶段,没有大量历史数据,可以直接修改Prisma Schema,将userId字段类型从Int改为String:

model Todo {
  id     Int    @id @default(autoincrement())
  text   String
  done   Boolean @default(false)
  userId String // 替换原有的Int类型
  user   User   @relation(fields: [userId], references: [id])
}

model User {
  id            String    @id @default(cuid()) // 推荐用String作为用户表ID,适配社交登录的字符串ID
  name          String?
  email         String?   @unique
  emailVerified DateTime?
  image         String?
  todos         Todo[]
  accounts      Account[]
  sessions      Session[]
}

修改后运行npx prisma migrate dev更新数据库结构。如果已有历史数据,需要额外处理数据迁移,将原有的Int类型userId转换为String。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 09:55:24