Flutter应用存储Github OAuth的client_id和client_secret是否为最佳实践?
结论:绝对不要在Flutter客户端存储
client_secret,推荐将token交换逻辑迁移到后端并配合PKCE流程 为什么不能在客户端存client_secret?
Flutter编译后的APK/IPA属于公共客户端,无法安全存储敏感信息:
- 攻击者可通过反编译工具轻松提取
client_secret,一旦泄露,对方能伪装你的应用调用GitHub API,滥用OAuth应用权限(比如获取用户隐私、操作仓库等)。 - 这完全违反OAuth 2.0安全规范,公共客户端(移动/前端应用)本身就不应该持有客户端密钥。
推荐的安全方案:后端代理token交换 + PKCE流程
把和GitHub的token交换逻辑放到你的后端API,客户端仅传递auth_code和PKCE相关参数,具体流程如下:
- 客户端初始化PKCE参数:
- 生成随机的
code_verifier(长随机字符串)。 - 对
code_verifier做SHA-256哈希,再进行base64url编码得到code_challenge。 - 调用Chrome Custom Tabs打开GitHub授权页面时,携带
client_id、code_challenge、code_challenge_method=S256及其他必要参数(如redirect_uri、scope)。
- 生成随机的
- 获取授权码并请求后端:
- 用户完成登录授权后,GitHub通过Deep Link返回
auth_code给客户端。 - 客户端将
auth_code和code_verifier一起发送到你的后端API接口。
- 用户完成登录授权后,GitHub通过Deep Link返回
- 后端完成token交换:
- 后端使用服务器端存储的
client_id、client_secret,加上收到的auth_code和code_verifier,向GitHub API发起POST请求获取token。 - 后端可选择直接返回GitHub的token给客户端,或者生成自己应用的会话token(更推荐,可自定义过期时间、权限范围,降低第三方token泄露风险)。
- 后端使用服务器端存储的
方案优势
- 彻底避免
client_secret泄露:敏感的client_secret仅在后端存储,客户端完全接触不到。 - PKCE增强安全性:即使
auth_code在传输过程中被拦截,没有对应的code_verifier也无法交换到有效token,防止授权码被滥用。 - 后端可控性更高:可对token进行缓存、权限校验、日志记录,后续扩展多平台登录逻辑时,无需修改客户端代码。
内容的提问来源于stack exchange,提问作者konkri
相关产品推荐
相关产品推荐

