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

Next-Auth集成Facebook Provider后无法获取邮箱/手机号的问题求助

Next-Auth + Facebook Provider 获取邮箱/手机号并存储到数据库的解决方案

问题核心

你配置了Facebook权限但会话仅返回基础信息,主要原因是:

  • Scope格式错误(Next-Auth要求空格分隔权限,而非逗号)
  • 未主动配置profile回调获取额外字段
  • 部分权限(如手机号)需Facebook应用审核或测试用户支持

解决方案步骤

1. 修正Facebook Provider的Scope配置

Next-Auth的Facebook Provider要求scope参数用空格分隔,同时明确指定Graph API返回的字段:

FacebookProvider({
  clientId: process.env.FACEBOOK_CLIENT_ID,
  clientSecret: process.env.FACEBOOK_CLIENT_SECRET,
  // 修正scope为空格分隔,保留需要的权限
  scope: 'email user_gender user_age_range',
  // 指定Graph API端点及需要返回的字段
  profileUrl: 'https://graph.facebook.com/me?fields=id,name,email,picture,gender,age_range'
})

2. 配置Profile回调自定义用户数据结构

通过profile回调提取并返回需要的用户字段:

FacebookProvider({
  // ...其他配置
  async profile(profile) {
    return {
      id: profile.id,
      name: profile.name,
      email: profile.email,
      image: profile.picture.data.url,
      gender: profile.gender,
      ageRange: profile.age_range
      // 若已获取手机号权限,添加:phone: profile.phone_number
    };
  }
})

3. 同步字段到JWT和会话

将自定义字段存入JWT并同步到前端会话:

export const authOptions = {
  providers: [/* Facebook Provider配置 */],
  callbacks: {
    async jwt({ token, user }) {
      // 首次登录时存入自定义字段
      if (user) {
        token.id = user.id;
        token.gender = user.gender;
        token.ageRange = user.ageRange;
        // token.phone = user.phone;
      }
      return token;
    },
    async session({ session, token }) {
      // 将token字段同步到会话
      session.user.id = token.id;
      session.user.gender = token.gender;
      session.user.ageRange = token.ageRange;
      // session.user.phone = token.phone;
      return session;
    }
  }
};

4. 在登录回调中存储用户到数据库

用户登录成功后,通过signIn回调将信息写入数据库:

export const authOptions = {
  // ...其他配置
  callbacks: {
    async signIn({ user }) {
      // 示例:检查用户是否已存在(以PostgreSQL为例)
      const existingUser = await db.query('SELECT id FROM users WHERE email = $1', [user.email]);
      
      if (!existingUser.rows.length) {
        // 不存在则创建新用户
        await db.query(
          'INSERT INTO users (id, name, email, image, gender, age_range) VALUES ($1, $2, $3, $4, $5, $6)',
          [user.id, user.name, user.email, user.image, user.gender, user.ageRange]
        );
      }
      
      return true; // 允许登录
    },
    // ...jwt和session回调
  }
};

5. 手机号权限说明

  • user_phone_number权限需要Facebook应用通过官方审核才能向普通用户请求
  • 测试阶段可使用Facebook开发者后台的测试用户,给测试用户分配该权限验证,无需审核

验证结果

在前端通过useSession检查会话数据:

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

function UserProfile() {
  const { data: session } = useSession();
  
  if (session) {
    console.log("用户会话数据:", session.user);
    // 应包含email、gender等字段
  }
  
  return <div>用户邮箱:{session?.user?.email}</div>;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 21:12:38