新闻详情

新闻详情

首页 / 资讯中心 / 详情

Bangumi 客户端 OAuth 2.0 认证实战指南:用 5 个问题搞懂 Token 管理

发布时间:2026/11/14 18:00:44来源:尧图网络
Bangumi 客户端 OAuth 2.0 认证实战指南:用 5 个问题搞懂 Token 管理
Bangumi 客户端 OAuth 2.0 认证实战指南用 5 个问题搞懂 Token 管理【免费下载链接】Bangumi:electron: An unofficial https://bgm.tv ui first app client for Android and iOS, built with React Native. 一个无广告、以爱好为驱动、不以盈利为目的、专门做 ACG 的类似豆瓣的追番记录bgm.tv 第三方客户端。为移动端重新设计内置大量加强的网页端难以实现的功能且提供了相当的自定义选项。 目前已适配 iOS / Android。项目地址: https://gitcode.com/GitHub_Trending/ba/Bangumi这篇文章拆解 Bangumi 客户端bgm.tv 第三方追番应用里的 OAuth 2.0 认证与 Token 管理实现授权码怎么换令牌、每个请求怎么带上令牌、令牌失效了怎么办、登出又清掉了什么。读完你可以对照仓库源码给自己项目的移动端认证层找一套能直接借鉴的做法。先拿地图令牌的一生分四步在进细节之前先把 Bangumi 客户端的认证主循环走一遍后文每个问题都挂在这条线上拿令牌用户在客户端里完成网页登录客户端向 bgm.tv 请求授权拿回一个code再用它换access_token默认有效期 7 天token_type为Bearer。带上令牌之后所有 API 请求在统一的 fetch 层里自动塞Authorization头业务代码不感知。续期与失效服务端返回invalid_token时打上outdate标记重新授权走代理接口最多尝试 2 次。登出一次性把令牌、cookie、用户信息全部重置回初始值并写回本地存储。第一次登录到底发生了什么一句话结论客户端不直接管密码它只干拿 code、换 token这一件事网页登录环节本身是站在 bgm.tv 的 OAuth 端点上完成的。流程分三步都在 src/stores/user/action.ts 里reOauth()带用户 cookie 请求/oauth/authorize从返回的页面里提取formhash表单防重放码。authorize(formhash)以表单方式 POST 提交授权服务端 302 到重定向地址客户端截住这个跳转从 URL 里解析出code。getAccessToken(code)拿code换令牌。最后一步是标准授权码模式核心就是这段简化自 src/stores/user/action.tsconst { status, data } await axiosWithProxy(axios, { method: POST, url: ${HOST}/oauth/access_token, headers: { Content-Type: application/x-www-form-urlencoded }, data: urlStringify({ grant_type: authorization_code, client_id: APP_ID, client_secret: APP_SECRET, code, redirect_uri: URL_OAUTH_REDIRECT, state: getTimestamp() }) })为什么值得注意的点state填当前时间戳这是 OAuth 对state参数的常规用法防止授权响应被错位使用。client_id/client_secret是 App Key定义在 src/constants/app.ts重定向地址${HOST}/dev/app定义在 src/constants/host.ts。换到令牌后调用updateAccessToken(data)把服务端返回的access_token、expires_in等字段整体写入 store 并save持久化。初始值在 src/stores/user/init.tsexpires_in: 6048007 天、token_type: Bearer。旧版本还有一条fetchAccessToken路径留在 src/stores/user/fetch.ts同样是授权码换令牌新流程以action.ts为准。令牌到手了。但手里有令牌不等于系统认为你登录了——下一节看它怎么判断。系统凭什么判断我还登录着结论先行它不只看令牌一个维度API 鉴权和网页 cookie 是两套独立的登录态另外还有一个outdate标记专门记录令牌已被服务端拒绝过。判断逻辑在 src/stores/user/computed.ts/** api 鉴权是否有效 */ computed get isLogin() { return WEB ? false : !!this.accessToken.access_token } /** 网页 cookie 是否有效 */ computed get isWebLogin() { return WEB ? false : !!this.userCookie.cookie }为什么拆两层因为 Bangumi 客户端里既有走 JSON API 的功能认access_token也有走网页 HTML 的功能认 cookie两者的有效期和失效方式完全不同。所以isLogin只回答API 调用带不带令牌。isWebLogin只回答内嵌网页视图能不能正常访问。outdate是个布尔状态请求被服务端回invalid_token时置位见后文 Q4界面层据此提示授权信息已过期。静态判断之外还有一次主动校验checkLogin()里如果距上次启动超过 1 分钟会延迟 8 秒请求一次个人中心页面看返回的 HTML 里有没有当前操作需要您…这类提示——有的话说明 cookie 静默失效了同样置outdate。这个检查顺便还能抓到formhash存下来备登出用。每个请求是怎么偷偷带上令牌的结论先行业务代码写请求时从不手动传令牌附加动作集中在统一请求层所有 API 请求收口到 src/utils/fetch/fetch.ts 的fetchAPIconst { accessToken } syncUserStore() if (accessToken.access_token) { if (WEB url.includes(API_HOST) !url.includes(API_V0)) { log(fetchAPI, ignored token:, url) } else { config.headers.Authorization ${accessToken.token_type} ${accessToken.access_token} } }注意那个WEB分支——这是同一套代码跑在 App 和浏览器里带来的差异Web 环境下令牌是用户手动填的storybook 场景直接往老 API 带反而会被拒所以 Web 端只放行api.v0这类明确支持令牌的端点其余只打日志。另外两个小设计所有 API 请求的 body 里都带了app_idGET 请求还会追加时间戳参数方便服务端识别调用方。api.v0 这条新接口的请求头不临时拼而是由 store 里预计算好的requestHeaders直接提供见 src/stores/user/computed.ts格式同样是Bearer token。收口带来的好处是换令牌存储方式、加签名、改代理只动这一层。 网络抽风、令牌过期会怎样结论先行它不追求永不掉线而是给每类故障配了有限次数的自动重试重试不动就明说让用户处理。这里有三条独立的容错线① 普通 GET 请求失败自动重试。src/utils/fetch/fetch.ts 里 GET 请求失败会 sleep 后调用retryCb重发次数上限由 src/utils/fetch/ds.ts 的FETCH_RETRY控制——原生端 2 次Web 端 0 次浏览器自己会重试。按 URL 参数做缓存键计数请求一旦成功计数清零。② 令牌失效触发重新授权。服务端返回invalid_token时先setOutdate()标记状态同时reOauth()走代理重新授权伪代码大概是这样for i in 0..2: // _reOauthCount 2最多尝试 2 次 拿 formhash → 提交授权 → 截 code → 换 token 成功 → 结束 4xx 失败 → 提示重新授权失败请重新登录保留现有登录信息 其他错误 → 提示重新授权失败请检查网络后重试这里有个容易误解的点重试耗尽时它不自动登出只是弹提示、保留现场。为什么注释里写得很清楚——4xx 通常是 cookie 失效导致此时清掉登录信息反而把还能用的令牌也扔了先让用户自己决定。③ 超时兜底。所有请求 20 秒超时FETCH_TIMEOUT配合 loading 提示避免请求永远挂起。登出之后它把哪些东西抹干净了结论先行登出 把五个状态字段重置回初始值并且把空值显式写回本地存储——清内存不够还得清磁盘否则下次启动init阶段还会从存储里读出旧令牌。实现就是 src/stores/user/action.ts 里的logout()logout () { setTimeout(() { this.setState({ accessToken: INIT_ACCESS_TOKEN, // 空令牌 默认 7 天有效期 userCookie: INIT_USER_COOKIE, // 空 cookie / UA setCookie: , userInfo: INIT_USER_INFO, // 空用户信息 outdate: false }) this.save(accessToken); this.save(userCookie) this.save(setCookie); this.save(userInfo) }, 0) }两个细节外层的setTimeout(…, 0)让重置在下一个事件循环执行避开调用栈里正在使用旧状态的地方防止竞态。四个save是刻意的本地存储里留下的是初始值而非旧值登出才真正落盘。INIT_ACCESS_TOKEN这些初始结构定义在 src/stores/user/init.ts重置和登录写的是同一套形状类型上天然对齐。顺带一提checkLogin抓到的formhash在这里派上用场网页侧登出要拿它拼 logout 链接这也是登录态检查时顺便记录它的原因。落地前对照这份清单给你自己项目的认证层做 review 时逐条勾一遍令牌换发走标准授权码模式state参数不为空client_secret不进公开渠道日志登录态是多维度的API 令牌、网页 cookie 分开判断并且有服务端拒绝过令牌的显式标记位请求收口到单一 fetch 层业务代码不手动拼Authorization头重试有次数上限比如重授权 2 次、GET 2 次失败后给用户明确文案而不是无限转圈重试失败不盲目清登录现场把决定权交给用户登出同时重置内存状态和本地存储空值显式落盘敏感字段cookie、令牌、用户信息一个不漏对照仓库时重点看 src/stores/user/ 下的action.ts拿令牌/登出/重授权、init.ts初始结构、computed.ts状态判断再配合 src/utils/fetch/ 的请求收口层基本就是 Bangumi 客户端整套认证机制的全部骨架。【免费下载链接】Bangumi:electron: An unofficial https://bgm.tv ui first app client for Android and iOS, built with React Native. 一个无广告、以爱好为驱动、不以盈利为目的、专门做 ACG 的类似豆瓣的追番记录bgm.tv 第三方客户端。为移动端重新设计内置大量加强的网页端难以实现的功能且提供了相当的自定义选项。 目前已适配 iOS / Android。项目地址: https://gitcode.com/GitHub_Trending/ba/Bangumi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

【外设】之大彩串口显示屏 2026/11/14 3:51:47

【外设】之大彩串口显示屏

大彩串口屏初步使用 1 .官网下载 STM32 屏幕 GUI 设计资料 http://www.gz-dc.com/category/typeid/4112 找到 STM32 Keil 工程,移植相关代码因项目而异进行移植,由于项目简单,本人只对用到的指令接口进行修改。 比如:注意事项&…

阅读更多 →
无法下载Windows系统iso文件 2026/11/12 23:59:09

无法下载Windows系统iso文件

当我遇到这个问题的时候,我打开了一个网站: 登录 然后我打算下载的时候: 突然那个官方的连接就可以下载了:

阅读更多 →
【清华代码熊】DeepSeek V4.1 Flash 后训练详解 2026/11/14 10:11:15

【清华代码熊】DeepSeek V4.1 Flash 后训练详解

📌 上期解析了 DeepSeek V4.1 Flash 模型架构改进,本期解析 DeepSeek V4.1 Flash 预训练/后训练技术: 🌟 预训练:45T 文本 多模态混合语料、直接训练 sparse attention(取消 DeepSeek V4 的 dense 冷启动&…

阅读更多 →
Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ... 2026/11/14 17:14:38

Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ...

文章主要内容和创新点 主要内容 本文聚焦于多模态大语言模型(MLLM)强化学习(RL)训练中的效率问题,提出了一个名为Shuffle-R1的框架。研究发现,当前RL训练存在两个关键缺陷: 优势值坍缩(Advantage Collapsing):批次中大多数优势值集中在零附近,导致有效梯度信号被淹…

阅读更多 →
PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction 2026/11/14 16:35:50

PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction

一、文章主要内容总结 本文聚焦于利用大型语言模型(LLMs)实现个人身份信息(PII)脱敏的研究,旨在解决传统脱敏方法(如基于规则的系统、领域特定命名实体识别(NER)模型)泛化能力差、跨格式/跨语境适应性弱的问题。 研究通过全面评估多种LLM架构(包括密集型LLM(D-LLM…

阅读更多 →
LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model 2026/11/14 3:51:43

LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model

文章主要内容和创新点 主要内容 本文聚焦于二进制图像-文本相关性评估任务(判断图像与文本“相关”或“不相关”),针对该任务中文本格式多样、相关性定义随场景变化等挑战,提出了基于多模态大语言模型(MLLM)的解决方案LLaVA-RE。 模型设计:LLaVA-RE基于LLaVA 1.5架构,…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉