NodeJS后端+Flutter移动端Google OAuth认证交互流程咨询
移动端 + NodeJS 后端 Google OAuth 2.0 集成流程(基于JWT + MongoDB)
一、核心通信逻辑(授权码模式,移动端首选)
授权码模式能避免客户端暴露敏感密钥,是移动端OAuth集成的标准方案,流程如下:
- 移动端请求后端生成Google OAuth授权URL
- 移动端通过WebView/系统浏览器打开该URL,用户完成Google登录授权
- Google将授权码返回至移动端配置的回调地址(如自定义Schema:
yourapp://google-oauth-callback) - 移动端把授权码传给后端
- 后端用授权码+自身的Google Client ID/Secret向Google换取Access Token和ID Token
- 后端解析ID Token获取用户邮箱、姓名等核心信息
- 后端在MongoDB中查找用户:存在则直接生成JWT;不存在则创建新用户再生成JWT
- 移动端接收并存储JWT,后续请求通过
Authorization: Bearer {JWT}完成身份验证
二、NodeJS 后端核心代码示例
先安装依赖:
npm install express jsonwebtoken google-auth-library mongoose
1. 基础配置
const { OAuth2Client } = require('google-auth-library'); const jwt = require('jsonwebtoken'); const mongoose = require('mongoose'); // 从环境变量读取,禁止硬编码敏感信息 const GOOGLE_CLIENT_ID = process.env.GOOGLE_CLIENT_ID; const GOOGLE_CLIENT_SECRET = process.env.GOOGLE_CLIENT_SECRET; const JWT_SECRET = process.env.JWT_SECRET; const REDIRECT_URI = "yourapp://google-oauth-callback"; // 需在Google Cloud Console提前配置 const oAuth2Client = new OAuth2Client(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, REDIRECT_URI);
2. 生成Google授权URL接口
给移动端调用,获取可跳转的授权地址:
app.get('/api/auth/google/url', (req, res) => { const authUrl = oAuth2Client.generateAuthUrl({ access_type: 'offline', // 可选,用于获取Refresh Token实现长期登录 scope: ['profile', 'email'], // 申请用户邮箱、基础信息权限 }); res.json({ authUrl }); });
3. 处理授权码,完成认证并返回JWT
app.post('/api/auth/google/token', async (req, res) => { try { const { code } = req.body; // 用授权码交换Google Token const { tokens } = await oAuth2Client.getToken(code); oAuth2Client.setCredentials(tokens); // 验证并解析ID Token const ticket = await oAuth2Client.verifyIdToken({ idToken: tokens.id_token, audience: GOOGLE_CLIENT_ID, }); const payload = ticket.getPayload(); const { email, name, picture } = payload; // 查找或创建用户 let user = await User.findOne({ email }); if (!user) { user = new User({ email, name, avatar: picture, password: undefined, // OAuth用户无需密码 }); await user.save(); } // 生成自定义JWT const token = jwt.sign({ userId: user._id }, JWT_SECRET, { expiresIn: '7d' }); res.json({ token, user: { id: user._id, email, name, avatar: user.avatar } }); } catch (err) { console.error(err); res.status(400).json({ message: 'Google认证失败' }); } });
4. MongoDB User模型示例
兼容邮箱密码登录和OAuth登录:
const userSchema = new mongoose.Schema({ email: { type: String, required: true, unique: true }, name: { type: String, required: true }, avatar: String, password: String, // 仅邮箱密码登录用户需要 }); const User = mongoose.model('User', userSchema);
5. JWT验证中间件
用于保护需要授权的接口:
const authMiddleware = (req, res, next) => { const token = req.headers.authorization?.split(' ')[1]; if (!token) return res.status(401).json({ message: '未授权' }); try { const decoded = jwt.verify(token, JWT_SECRET); req.userId = decoded.userId; next(); } catch (err) { res.status(401).json({ message: '无效Token' }); } }; // 使用示例:获取用户个人信息 app.get('/api/user/profile', authMiddleware, async (req, res) => { const user = await User.findById(req.userId).select('-password'); res.json(user); });
三、移动端侧关键操作
- 调用后端
/api/auth/google/url获取授权URL - 用系统浏览器或WebView打开该URL,引导用户完成Google登录授权
- 监听回调地址,提取URL中的
code参数 - 将
code通过POST请求传给后端/api/auth/google/token - 接收后端返回的JWT,存储到安全位置(如Keychain、AsyncStorage)
- 后续所有接口请求,在请求头中携带
Authorization: Bearer {JWT}
四、重要注意事项
- 敏感信息保护:Google Client Secret绝对不能出现在移动端代码中,所有密钥交互必须在后端完成
- 回调地址配置:需在Google Cloud Console的OAuth客户端设置中,添加移动端的自定义Schema或后端回调地址
- Refresh Token管理:若需要长期登录,需在生成授权URL时指定
access_type: 'offline',后端可存储Refresh Token用于过期后自动刷新Access Token - 权限范围:根据实际需求申请最小必要权限,避免过度申请用户隐私信息
内容的提问来源于stack exchange,提问作者Jonathan Ato Markin
相关产品推荐
相关产品推荐

