生产环境Passport.js报TokenError: Malformed auth code问题求助
Passport.js Google OAuth2生产环境出现TokenError: Malformed auth code的解决方案
问题描述
使用Passport.js实现Google OAuth2登录功能,开发环境运行正常,但部署到生产环境后触发以下错误:
TokenError: Malformed auth code. at Strategy.OAuth2Strategy.parseErrorResponse (/var/task/node_modules/passport-oauth2/lib/strategy.js:373:12) at Strategy.OAuth2Strategy._createOAuthError (/var/task/node_modules/passport-oauth2/lib/strategy.js:420:16) at /var/task/node_modules/passport-oauth2/lib/strategy.js:177:45 at /var/task/node_modules/oauth/lib/oauth2.js:191:18 at passBackControl (/var/task/node_modules/oauth/lib/oauth2.js:132:9) at IncomingMessage.<anonymous> (/var/task/node_modules/oauth/lib/oauth2.js:157:7) at IncomingMessage.emit (node:events:539:35) at endReadableNT (node:internal/streams/readable:1345:12) at processTicksAndRejections (node:internal/process/task_queues:83:21)
已尝试设置access_type: 'offline'、decodeUri等方法,耗时四天未解决。
相关代码片段
认证路由代码
const express = require('express'); const router = express.Router(); const passport = require('passport'); const { auth, requestdecode } = require('../middleware/reqAuth'); require('../config/passportAuth'); const { signToken } = require('../middleware/jwt'); router.get('/failed', (req, res) => { res.status(401).json({ success: false, message: 'failure' }); }); router.post('/success', auth, (req, res) => { res.status(200).json({ success: true, message: 'successful', user: req.user }); }); router.get( '/google', passport.authenticate('google', { scope: ['email', 'profile'], session: false, accessType: 'offline', prompt: 'consent' }) ); router.get( '/google/callback', passport.authenticate('google', { session: false, failureRedirect: '/failed' }), function (req, res) { try { const token = signToken(req); res .cookie('jwt_auth', token, { maxAge: 11 * 60 * 60 * 1000, httpOnly: false, sameSite: false }) .redirect(process.env.CLIENT_URL); } catch (err) { throw err; } } ); router.get('/logout', (req, res) => { req.session = null; req.logout(); res.redirect('/auth/google'); }); module.exports = router;
Passport配置代码
require('dotenv').config(); const passport = require('passport'); const GoogleStrategy = require('passport-google-oauth20').Strategy; const User = require('../model/user'); passport.serializeUser(function (user, done) { done(null, user); }); passport.deserializeUser(function (user, done) { done(null, user); }); passport.use( new GoogleStrategy( { clientID: process.env.CLIENT, clientSecret: process.env.CLIENT_SECRET, callbackURL: process.env.CALLBACK_URL, userProfileURL: 'https://www.googleapis.com/oauth2/v3/userinfo', accessType: 'offline', passReqToCallback: true }, async function (request, accessToken, refreshToken, profile, done) { console.log(request); try { let existingUser = await User.findOne({ oauthId: profile.id }); if (!existingUser) { const newUser = await User.create({ oauthId: profile.id, name: profile.displayName, email: profile.emails[0].value, imageLink: profile.photos[0].value }); return done(null, newUser); } done(null, existingUser); } catch (error) { console.log(error); } } ) );
排查与解决步骤
1. 严格校验回调URL一致性
- 登录Google Cloud控制台,进入OAuth 2.0客户端ID配置页面,确保已授权重定向URI与代码中
process.env.CALLBACK_URL完全匹配,包括协议(必须是HTTPS)、域名、路径,不能有任何拼写错误或多余字符。 - 注意:如果部署在第三方平台,需确认平台分配的实际域名是否与配置一致,避免使用本地测试域名。
2. 修正参数大小写问题
OAuth2标准参数为access_type(下划线),将路由和Passport配置中的accessType: 'offline'统一改为access_type: 'offline',避免因参数名兼容问题导致的异常。
3. 检查请求参数是否被篡改
在回调路由最上层添加中间件,打印接收到的auth code,对比开发环境的code格式,确认生产环境中code是否被代理、CDN或平台中间件修改:
router.get('/google/callback', (req, res, next) => { console.log('Received auth code:', req.query.code); next(); }, passport.authenticate('google', { session: false, failureRedirect: '/failed' }), ...);
如果code格式异常(如被重复编码),需调整平台的请求处理规则。
4. 验证生产环境变量配置
在Passport配置中添加日志,打印clientID、clientSecret、callbackURL的值,确保生产环境的环境变量没有多余空格、换行或配置错误:
console.log('Google OAuth Config:', { clientID: process.env.CLIENT, callbackURL: process.env.CALLBACK_URL });
5. 修正Cookie安全配置
生产环境下sameSite: false必须配合secure: true(仅HTTPS环境生效),否则浏览器可能拦截Cookie导致认证流程中断,修改Cookie配置:
res.cookie('jwt_auth', token, { maxAge: 11 * 60 * 60 * 1000, httpOnly: false, sameSite: 'none', secure: true })
6. 升级依赖版本
检查passport、passport-google-oauth20、oauth等依赖的版本,旧版本可能存在生产环境兼容性问题,执行以下命令升级到最新稳定版:
npm update passport passport-google-oauth20 oauth
内容的提问来源于stack exchange,提问作者Atul Chourasiya
相关产品推荐
相关产品推荐

