参考博客

设计背景

目前主流应用都支持多端的登录,比如,bilibili,既可以在网页端登录,移动端APP登录,微信小程序登录等。
校园AI助手,可以在网页端,微信公众号,企业微信号,公司其他应用接口调用等多端进行登录和访问,所以,针对不同方式访问系统平台的,都具有不同的形式(这种形式可能表现在使用方面,安全方面、不同的生存周期)等等,所以,需要基于token的多平台进行用户的身份验证。

Token分类

1、用户可以在web浏览器中登录系统 — 浏览器token
2、用户可以在手机端(公众号/企业号)登录系统 — 移动端token
3、用户可以在开放接口(一键通)登录系统 — API应用token 接口访问token
4、用户在手机处理登录状态时通过手机收吗授权PC登录(比较常见) — pc与移动端相互授权token
5、用户在PC处理登录状态可以通过手机扫码授权手机登录(使用较少) — pc与移动端相互授权token

考虑成本

使用成本
账号密码需要用户打开页面然后逐个输入
二维码需要用户掏出手机进行扫码操作
变化成本
账号和密码发生变化时,需要额外记忆和重新键入新密码
API应用的 appId/appSecret发生变化时,第三方应用需要重新在代码中修改并部署
(后期可以考虑在数据库存储信息,同时存入缓存,动态更新)
授权二维码发生变化,需要用户重新打开手机应用进行扫码。

环境风险

账号密码信息容易出现被偷窥的风险
黑客可以通过抓包等一些手段获取系统加密数据,然后伪造用户登录,存在被抓包、伪造的风险。

可调控属性

使用频率:比如账号密码等私密信息在网络中传送的频率。
有效时间:登录凭证从创建到失效的生存时间。

最终的目标是:安全和影响。

安全和隐私性主要体现在

  • token不容易被窃取和盗用——通过对传送频率控制
  • token即时被窃取,产生的影响也是可控的——通过对有效时间的控制

遵守原则
变化成本高的token不要轻易发生改变(根据账号、密码生成的token)
不轻易发生变化的token要减少曝光频率(减少网络传输次数)
曝光频率高的token的生存周期要尽量短

Token层级关系

密码层: 账号 + 密码, apiId + apiKey(传统的用户与系统约定的数字身份认证方式)
会话层:web_token,mobile_token,api_token (用户登录后会话生命周期的会话认证)
调用层:access_token (用户在会话期间调用程序接口的凭证)
应用层:map_token (用户获取了接口调用权限后的一些场景或身份认证应用(扫码登录等))
—— 用户登录,有时效的优惠券发放,有时效的二维码授权,具有时效的手机邮箱验证码、多个不同平台调用同一套API接口,多个平台使用同一个身份认证系统

以上的token信息都具备不同的生命周期

会话token
web_token mobile_token api_token
web_token 生存周期不宜过长,因为web环境一般是公用环境,被人盗取的风险较大,同时,PC端的键盘输入相较于移动端会更便捷
mobile_token 生存周期长, 移动端 - 手机属于个人用户极其私密的平台,跟他人接触机会不大,同时,键入密码需要在手机屏幕上键入,多少会有点不方便。
api_token 基本上,一个应用的apiId和apiKey在定义之后,基本是很难去改动的。同时,应用的apiId和apiKey可能是写在代码层面上的。
所以相对来说,也是非常私密的信息,一般很难被窃取到,所以相对应的api_token的生命周期也可以是很长的。

接口token
access_token
主要作为 访问服务端api接口 的凭证
使用具有较长生命周期的会话token来换取接口访问的token
access_token,曝光的频率是和接口的调用频率相关的,属于高频使用的凭证。
所以,为了照顾其隐私性,尽量减少其生命周期,即使不小心被截获了,也不会造成太大的影响。
同时,增加access_token, 也可以让具有不同生命周期的会话token,在最后调用api的时候,都有统一的认证方式。

map_token
由已经登录的移动端app来扫码认证pc端系统,并完成pc端系统的登录
主要步骤
1、移动端完成用户身份认证登录app
2、未登录的pc根据二维码生成一个匿名的map_token
3、移动端扫码后在db中生成map_token和用户关联(完成签名)
4、db同时针对此用户生成一个web_token
5、pc端一直以map_token为参数查找此命名用户的web_token
6、pc端根据web_token 去获取access_token
7、后续正常的调用接口工作
map_token 生存周期为2分钟,2分钟后过期删除
没有使用时,每1分钟变1次
被使用后,立刻删除掉