【鉴权】前后端鉴权方案
Session-Cookie
用户登录后,在服务端为这个用户生成一个唯一的 SessionId,并将其存储在 Cookie 中。
之后的每个请求都在 Cookie 中携带 SessionId,后端根据 SessionId 进行鉴权。
- 优点
- Session 数据存储在服务端,当用户登录和注销时,只需要添加删除对应的 Session 就可以了,方便管理。
- 缺点
- Session 存储在服务端,增大了服务端的开销,用户量大的时候会降低服务器性能。
- 客户端如果禁用 Cookie 就无法鉴权了。
Token
用户登录后,在服务端生成一个 Token 字符串并返回到客户端,客户端在之后的请求中携带 Token 访问服务器,服务端只需要验证令牌的有效性即可。
一般 Token 的组成:uid(用户唯一身份标识)+ time(当前时间的时间戳)+ sign(签名,Token 的前几位以哈希算法压缩成的一定长度的字符串)。
- 优点
- 服务端无状态化,可扩展性好:Token 机制不需要在服务端存储会话信息,因为 Token 自身包含了其所标识用户的相关信息,这有利于在多个服务间共享用户状态。
- 缺点
- Token 比 SessionId 更长,需要消耗更多流量。
- Token 需要解密,所以更耗费性能。
- 有效期短:为了避免 Token 被盗用,一般 Token 的有效期会设置的比较短。
JWT(JSON Web Token)鉴权
通过 Token 方式鉴权,服务端获取用户信息需要从 Token 中解密出用户 Id,然后在数据库中查询,增加了查库带来的性能消耗。
JWT 就是携带了用户信息的 Token,服务端用自己的私钥解密 Token 获取用户信息,而不是去数据库中查询。
单点登录(Single Sign On)
单点登录是为了在多个不同系统之间共享用户的登录状态,比如用户在 A 系统登录后,再访问 B 系统,B 系统通过共享拿到了用户的登录状态,就不需要用户重复登录了。
要实现登录状态共享,需要引入一个 CAS(Central Authentication Service)中央授权服务。
单点登录原理:
- 用户访问网站 A,点击登录,这时跳转到 CAS 认证服务的登录页面,在 url 中携带登录后需要重定向的目标地址 redirectURL。
- 用户在 CAS 的登录页面登录后,CAS 在自己的域名下设置一个 cookie,用来标记用户的登录状态,记作 TGC,根据 TGC 同时生成一个授权令牌 ST,重定向到 redirectURL 并在 url 中携带 ST 信息。
- 网站 A 在 url 中获取到 ST 信息后,将其保存到自己的域名下,后续就通过 ST 向 CAS 获取用户的登录状态。
- 用户访问网站 B,点击登录,跳转到 CAS 的登录页面,这时登录页面可以获取到用户在 A 网站登录后生成的 TGC,根据这个 TGC 生成授权令牌 ST 并重定向回网站 B,这样就实现了登录状态的共享。
注意:cookie 设置为 SameSite: "strict"
时无法实现单点登录,因为只能在同站访问时携带 cookie。
OAuth 和信任登录
OAuth 是一种授权机制。数据的所有者(用户)告诉系统(支付宝、微信等提供 OAuth 认证服务的厂商),同意授权第三方应用(CSDN、思否等)进入系统,获取这些数据。系统从而产生一个短期的进入令牌(Token),用来代替密码,供第三方应用使用。
信任登录是指所有不需要用户主动参与的登录,OAuth 其实就是信任登录的缩影。
联合登录
APP 内嵌 H5 的使用场景下,当用户从 APP 进入内嵌的 H5 时,我们希望 APP 内已登录的用户能够访问到 H5 内受限的资源,而未登录的用户则需要登录后访问。
这里思路主要有两种,一种是原生跳转内嵌 H5 页面时,将登录态 Token 附加在 URL 参数上,另一种则是内嵌 H5 主动通过与原生客户端制定的协议获取应用内的登录状态。
一键登录
一键登录就是通过网络运营商提供的 SDK,从网络运营商处获取用户信息(手机号),服务端用手机号进行登录或注册操作,完成一键登录。
一键登录的可行性要归功于手机卡的实名制,能不能做则取决于对应的网络运营商是否提供相关服务。