Express中间件中使用Refresh Token生成新Access Token后,res.cookie设置Google认证会话Cookie无效问题排查
问题分析与解决方案
看起来你已经成功获取到新的Access Token,但Cookie没有正确同步到浏览器里,我帮你梳理几个核心问题点和对应的修复方法:
1. Axios请求参数格式不规范(虽请求成功,但存在潜在风险)
Google OAuth2的令牌刷新接口要求请求体使用application/x-www-form-urlencoded格式,而你的代码直接把参数对象作为POST数据传递,Axios默认会将其序列化为JSON格式。虽然Google可能兼容了这种非标准写法,但这不是推荐用法,也可能导致隐式问题。
修复方法:用URLSearchParams构造符合要求的请求体:
const data = new URLSearchParams({ client_id: process.env.GOOGLE_CLIENT_ID, client_secret: process.env.GOOGLE_CLIENT_SECRET, refresh_token: refresh_token, grant_type: 'refresh_token' }); const response = await axios.post( 'https://accounts.google.com/o/oauth2/token', data );
2. Cookie的Path范围限制
你的googleDriveRouter可能挂载在子路径下(比如/api/drive),而res.cookie默认的path是当前路由的路径。这意味着这个Cookie只会在访问该子路径时生效,你在浏览器根路径下自然看不到它。
修复方法:显式设置path: '/',让Cookie在整个站点范围内生效:
res.cookie('google-auth-session', googleAuthToken, { maxAge: 60 * 60 * 1000, httpOnly: true, path: '/' // 添加这一行,确保Cookie全局可见 });
3. 代码语法错误导致请求未正常收尾
你的代码存在两处语法/逻辑问题:
if块内部多了一对不必要的嵌套大括号- 当
googleAuthToken存在或无refresh_token时,没有调用next(),会导致请求卡住,无法向浏览器发送响应,Cookie也就不会被写入
修复后的完整中间件代码:
googleDriveRouter.use(async (req, res, next) => { // Verify if google auth token is set in the cookies and not expired let googleAuthToken = req.cookies['google-auth-session']; const refresh_token = req.cookies['google-auth-refresh-token']; if(!googleAuthToken && refresh_token) { // Generate new access token if refresh token exists const data = new URLSearchParams({ client_id: process.env.GOOGLE_CLIENT_ID, client_secret: process.env.GOOGLE_CLIENT_SECRET, refresh_token: refresh_token, grant_type: 'refresh_token' }); const response = await axios.post( 'https://accounts.google.com/o/oauth2/token', data ); googleAuthToken = response.data.access_token; // Set new access token as cookie res.cookie('google-auth-session', googleAuthToken, { maxAge: 60 * 60 * 1000, httpOnly: true, path: '/' }); console.log("middleware", response.data); } // Ensure request proceeds regardless of token refresh status next(); });
额外排查点
- 检查浏览器Application面板时,切换到对应路由的Path下查看Cookie(比如路由是
/api/drive,就看/api/drive路径下的Cookie列表) - 确认没有其他中间件在后续流程中覆盖了
google-auth-session这个Cookie - 确保后续路由处理函数最终发送了响应(比如调用
res.send()、res.json()等),否则Cookie不会被写入浏览器
内容的提问来源于stack exchange,提问作者fitMath
相关产品推荐
相关产品推荐

