使用passport-github集成GitHub OAuth时无法获取refreshToken的问题
解决GitHub OAuth获取refreshToken及自动刷新accessToken的问题
首先,你拿不到refreshToken的核心原因是没有在授权请求中添加offline_access权限范围。GitHub OAuth2规定,只有明确请求offline_access scope,才会返回refreshToken,否则只会返回短期有效的accessToken。
第一步:修改Passport配置获取refreshToken
更新你的passport-github策略配置,添加scope: ['offline_access']参数,这样用户授权时GitHub会返回refreshToken:
var GitHubStrategy = require('passport-github').Strategy; passport.use(new GitHubStrategy({ clientID: GITHUB_CLIENT_ID, clientSecret: GITHUB_CLIENT_SECRET, callbackURL: "http://127.0.0.1:3000/auth/github/callback", scope: ['offline_access'] // 必须添加这个scope才能拿到refreshToken }, function(accessToken, refreshToken, profile, done) { // 现在refreshToken会被正常传入,把它和accessToken、用户信息一起存入数据库 // 示例:假设你有User模型 User.findOrCreate({ githubId: profile.id }, { accessToken: accessToken, refreshToken: refreshToken, githubProfile: profile }, function(err, user) { return done(err, user); }); } ));
第二步:用refreshToken自动刷新accessToken
当accessToken过期(GitHub默认有效期8小时),无需用户重新认证,直接在后端调用GitHub的token接口,用保存的refreshToken换取新的accessToken:
刷新token的后端代码示例
const axios = require('axios'); // 或使用node-fetch等HTTP库 async function refreshAccessToken(savedRefreshToken) { try { const response = await axios.post('https://github.com/login/oauth/access_token', { client_id: GITHUB_CLIENT_ID, client_secret: GITHUB_CLIENT_SECRET, grant_type: 'refresh_token', refresh_token: savedRefreshToken }, { headers: { 'Accept': 'application/json' } }); // GitHub可能会返回新的refreshToken,建议替换数据库中旧的refreshToken return { newAccessToken: response.data.access_token, newRefreshToken: response.data.refresh_token || savedRefreshToken }; } catch (err) { console.error('刷新token失败:', err.response?.data || err.message); // 如果刷新失败(比如用户撤销了授权),再引导用户重新认证 throw err; } }
关键注意事项
- 安全存储refreshToken:务必加密存储refreshToken,不要明文存在数据库或前端,避免泄露后被他人滥用。
- refreshToken的有效性:GitHub的refreshToken不会自动过期,但如果用户在GitHub设置中撤销了你的应用授权,或者refreshToken被多次使用(部分场景下会失效),此时才需要引导用户重新认证。
- 版本兼容性:确保你使用的
passport-github版本支持传递scope参数,若版本过旧,建议升级到最新版。
内容的提问来源于stack exchange,提问作者Umar Rasheed
相关产品推荐
相关产品推荐

