【鉴权】前后端鉴权方案

2023/06/07 09:38:51

用户登录后,在服务端为这个用户生成一个唯一的 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)中央授权服务。

单点登录原理:

  1. 用户访问网站 A,点击登录,这时跳转到 CAS 认证服务的登录页面,在 url 中携带登录后需要重定向的目标地址 redirectURL。
  2. 用户在 CAS 的登录页面登录后,CAS 在自己的域名下设置一个 cookie,用来标记用户的登录状态,记作 TGC,根据 TGC 同时生成一个授权令牌 ST,重定向到 redirectURL 并在 url 中携带 ST 信息。
  3. 网站 A 在 url 中获取到 ST 信息后,将其保存到自己的域名下,后续就通过 ST 向 CAS 获取用户的登录状态。
  4. 用户访问网站 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,从网络运营商处获取用户信息(手机号),服务端用手机号进行登录或注册操作,完成一键登录。

一键登录的可行性要归功于手机卡的实名制,能不能做则取决于对应的网络运营商是否提供相关服务。

参考

一文教你搞定所有前端鉴权与后端鉴权方案,让你不再迷惘open in new window