GitHub设备流中CLI场景下如何安全使用刷新令牌?
解决GitHub设备流CLI刷新令牌无需暴露client_secret的问题
首先明确:GitHub的OAuth2实现允许**公共客户端(比如CLI这类无法安全存储client_secret的应用)**在刷新令牌时无需提供client_secret,核心要做两步:
1. 初始授权时请求offline_access scope
在发起设备流的授权请求(获取设备码的环节),必须把offline_access加入到scope参数里。比如你原本的scope是repo read:user,就要调整为:
scope=repo%20read:user%20offline_access
只有加上这个scope,GitHub才会在授权成功后返回refresh_token——缺了这个参数,哪怕用户完成授权也拿不到刷新令牌。
2. 用refresh_token刷新access_token
当access_token过期时,调用GitHub的令牌刷新端点POST https://github.com/login/oauth/access_token,提交以下application/x-www-form-urlencoded格式的参数:
client_id: 你的OAuth App的client ID(这个可以安全写在CLI代码里,属于公开信息)grant_type: 固定为refresh_tokenrefresh_token: 之前授权成功后拿到并妥善存储的刷新令牌
这个请求完全不需要client_secret,GitHub会验证client_id和refresh_token的合法性,返回新的access_token(可能还会返回新的refresh_token,记得替换存储的旧值)。
额外注意事项
- 安全存储refresh_token: 把refresh_token存在用户本地的安全位置,比如Linux/macOS下的
~/.your-cli/config(权限设为600,仅当前用户可读),Windows下的%APPDATA%/YourCLI/config.json,避免被其他用户或程序读取。 - 处理刷新失败: 如果刷新请求返回
invalid_grant错误,说明refresh_token已经过期或失效(比如用户撤销了授权、修改了密码),这时候需要重新触发设备流让用户重新授权。 - refresh_token有效期: GitHub的refresh_token默认有效期是6个月,期间如果持续使用刷新,会自动续期(返回新的refresh_token),但如果超过6个月未使用就会失效。
内容的提问来源于stack exchange,提问作者Nicholas Haley
相关产品推荐
相关产品推荐

