用户权限认证

本文会很长,若是对你前端道路上有帮助,建议收藏,慢慢熟悉和消化,毕竟一口吃不成我这样(胖)。那我们就开始吧。

场景/现象

我在工作中发现很多同事和应聘者对用户鉴权都不是了解的很清晰。但是这块知识前端开发者每天都会与之打交道,虽说编程实现是后端开发。但对于一个有追求,有追求于更好的前端或全栈的前端来说,你需要熟悉这块知识,熟悉常见的用户鉴权有哪些以及整个流程是怎么交互的。

我会写一些 Demo,老话说的好,眼过千遍不如手过一遍。所以我希望如果你还不是特别清晰这块,可以 clone 到本地跑一跑,加强理解。然后再结合实际,看看自己公司的这块是怎么玩的。

你将 get 到

大纲/目录

  • Cookie/Session 认证
  • JWT 认证和 Token 认证
  • OAuth2 认证
  • SSO 单点登录
  • LDAP 认证
  • 扫码登录
  • 总结

Cookie 我会简单快速介绍下,因为你多多少少会了解,所以我会帮着串联回忆下。对于概念可以阅读 MDN 上的介绍 Cookie

可以通过浏览器控制台 Application > Cookies 查看。

  • Name/Value,
  • Domain,默认当期域名(同级域名),比如 yy.xxx.com。此时 zz.xxx.com 获取不到。如果想要获取到,那可以设置成父域名 xxx.com。所以 Domain 可以用来子域名间的通信,二级域名跳转就是这么玩的。
  • Path,就是 Cookie 生效路径。
  • Max-Age,有效期,默认是毫秒,只读。就是说超过这个时间,浏览器会自动删除。你肯定也想到 HTTP1.0 Expires,基本是废弃了。
  • Size,大小,只读。最大 5 M。
  • HttpOnly,默认是 false,就是可以通过 document.cookie 获取。
  • Secure,在 HTTPS 里使用,传输过程会加密。
  • SameSite,Chrome 提出的跨域共享 Cookie。
  • 客户端浏览器访问服务端页面。
  • 服务端收到该客户端浏览器请求后,创建 Session 生成 sessionId。
  • 在响应请求中设置 Cookie,属性为 sessionId。
  • 客户端浏览器收到后保存 sessionId,再次请求会在请求头设置,服务端可获取。
  • 服务端验证 sessionId 是否存在,即验证用户权限。

负载不大时完全没问题,玩的溜溜的。是,或许我们不会进入负载量上亿的大厂,也碰不到下面说的问题,但是我们还是应该知道这类边界情况,因为我们是专业的。一旦负载上亿了,我们是可以搞个负载均衡,把 sessionId 缓存到 Redis,所有的机器都来这访问,但这种方式一来会增加单点失败的可能性,二是 Redis 机器要是挂了,所用用户都得重新登录,这该如何收场?

JWT 认证和 Token 认证

JWT 价值

你应该会发现到 Cookie/Session 这种有状态的已经很难适应现在互联网的应用了,尤其是移动端的应用。所以我们需要一种无状态的方式,JWT(JSON Web Token)就是一个很好的选择。但有一点要记住:JWT 解决的是服务端 Cookie/Session 存储问题,不是数据传输安全。数据传输安全是 https,ssl 等要解决的问题。

JWT 组成

三段式 Header.Payload.Signature

  • Header,标记签名的算法,会 Base64。
  • Payload,存用户信息会,会 Base64。
  • Signature 验证签名,secret 密钥要保存好。

Header 和 Payload 虽然经过 Base64 加码,但是是可以解码的,所以可以存放一些用户的基本信息,隐私数据不要放到 Payload。

为什么 secret 密钥一定要存好?我们知道 Payload 可以更改,但是服务端获取到 Signature 后会用 secret 做个验证防止内容更改,所以说密钥要存好,且要定时更换。

JWT 交互

  • 客户端浏览器发起请求,服务端通过 JWT 生成一个 Token,返回给客户端浏览器。
  • 客户端浏览器存储起来,可以存在 sessionStorage。
  • 客户端浏览器后续请求带上这个 Token,服务端验证 Token 识别用户信息。
  • Token 有一个时效性,超时需重新获取,所以前端可以在请求方法中做个拦截器 interceptors。

Token 认证和 JWT 认证

  • 客户端浏览器请求中,其实只要用户信息 Payload 就好,对于 Header 和 Signature 都不需要,Redis 存储用户和 Token 对应好就行,所以 Token 适合做 API 请求认证,需要服务器存储用户和 Signature 关系。
  • JWT 不需要服务器存储用户和 Signature 关系,只要验证签名就好,所以 JWT 适合做一次行验证,比方邮箱激活账号。

Token 认证和 JWT 认证安全

上面说了 JWT 要解决的是 Cookie/Session 存储问题。对于安全性:

  • 缩短 Token 有效时间。
  • 定时替换 secret。
  • 使用 HTTPS 加密协议。
  • 对标准字段 iss、sub、aud、nbf、exp 进行校验。

OAuth2 认证

有人问第三方登录是如何实现的,比如微博、微信或 Github 登录。其实这种方式是 OAuth2 形式,具体表现为:点击跳转到第三方页面,然后再跳回来。

SSO 单点登录

LDAP 认证

扫码登录

总结