通过Google OAuth API仅获邮箱,如何获取用户姓名并保存至数据库?
解决Google OAuth获取用户名字和姓氏的问题
你现在只能拿到邮箱,核心原因是OAuth授权时没请求获取用户基本信息的权限范围(Scopes),加上代码里的异步逻辑有小问题,按下面步骤调整:
1. 确保授权请求包含正确的Scopes
在引导用户跳转到Google授权页面时,必须把profile和email加入请求的scope列表,示例scope参数应该是:
scope=profile email
或者完整的URL形式:
https://accounts.google.com/o/oauth2/v2/auth?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=code&scope=profile%20email
只有请求了profile权限,你的access_token才能拿到用户的given_name(名字)和family_name(姓氏)。
2. 验证Access Token的权限(可选)
如果不确定token有没有权限,可以调用Google的Token Info接口检查:
curl "https://oauth2.googleapis.com/tokeninfo?access_token=YOUR_ACCESS_TOKEN"
返回结果里的scope字段应该包含https://www.googleapis.com/auth/userinfo.profile和https://www.googleapis.com/auth/userinfo.email。
3. 修复代码里的异步逻辑问题
原代码用回调处理oauth2.userinfo.get,但外层是async函数,这种写法会导致return user无法正确返回结果,改成Promise形式更稳妥:
google: async function (req) { const { google } = require("googleapis"); const { OAuth2 } = google.auth; const oauth2Client = new OAuth2(); oauth2Client.setCredentials({ access_token: req.body.access_token }); const oauth2 = google.oauth2({ auth: oauth2Client, version: "v2", }); try { // 改用Promise形式调用,适配async/await const res = await oauth2.userinfo.get(); console.log(res.data); const user_data = new User({ first_name: res.data.given_name || "", last_name: res.data.family_name || "", email: res.data.email, }); const user = await user_data.save(); return user; } catch (err) { // 这里加上错误处理,比如打印日志或返回错误信息 console.error("获取用户信息失败:", err); throw err; // 抛出错误让上层处理 } }
注意事项
- 如果用户的Google账号没有设置公开的名字信息,
given_name或family_name可能为空,代码里最好做一下空值兜底处理。 - 确保你的Google Cloud项目里,OAuth同意屏幕已经配置好,并且
profile和email权限是已添加的。
内容的提问来源于stack exchange,提问作者John Oliver
相关产品推荐
相关产品推荐

