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
相关产品推荐
相关产品推荐

