目录

    • 前言
    • 传统方式下的身份认证
    • token如何实现身份认证
      • 单token续期方案
      • 双token续期方案
    • 小结

前言

B/S架构大家应该都不陌生,web1.0时代,用户通过个人电脑浏览网站,单项获取信息,比如我们浏览新闻,查阅资料等。web2.0很快就到来,和1.0相比,用户可以随时随地分享自己的信息。这个时候就涉及到了我们的身份认证。当我们使用http无状态请求访问资源服务的时候,服务端是如何知道我们的身份的,我们今天就来聊一聊。

传统方式下的身份认证

传统方式的身份认证,我们要从cookie和session说起来,我们先回顾一下cookie和session是有什么特点吧。

  • Cookie:存储在客户端的,客户端专门存东西的一个标识。

    1.能存储的东西很少,基本上只能存储4k左右的东西2.能被手动清除,不续期的情况下,只有20分钟的有效期3.Cookie安全问题,别人能从本地Cookie中获取信息4.Cookie不能直接存储中文,如果需要,则需要进行url转码5.不能跨域,不能跨域,不能跨域。
  • Session:存储在服务器端的,服务端专门存东西的一个标识。

    1.安全性:Session的安全性比Cookie的安全性要高2.性能:当服务器访问较多,比较占用性能3.生命周期:异常关机会造成Session的销毁,默认存储30分钟4.Session的钝化以及活化 钝化:服务器正常关闭后,tomcat会自动将Session数据写入硬盘的文件中 活化:服务器再次启动后,从文件中加载数据到Session中 5.浏览器关闭后再次重启SessionId的地址值不为同一个 4.访问范围:Session为一个浏览器共享Cookie为多个浏览器共享

基于 cookie、session 的身份认证中,用户登录后,服务器会为登录用户创建一个 session,cookie的验证是有状态的,sessionid 会保存 在cookie 中。当用户登录成功后,之后的每次请求都会携带cookie。服务器通过 cookie 中的 sessionid 找到内存中的 session 数据,来验证用户身份,从而在响应中返回相应的数据。我们可以参照下图进行理解


这个图看着是没什么问题了对不,以前大多数B/S架构都采用这种实现方式,有的同学就说了:“我现在这么实现也ok啊,我干嘛还要去研究那个token呢?”,那你们可以想一想,当你的后端服务需要水平扩展的时候,你的session怎么办?当然我们也是有一些常规做法的。例如服务之间的session同步方案、分布式缓存方案、用户负载方案。我们一个一个来说。

1.session同步,就是在用户登录成功产生session之后,在你的各个服务上进行session同步,保证请求能够畅通访问其他服务,这个开销不得不说是很大的。
2.分布式缓存,将session存储在分布式缓存中,所有服务都从缓存中获取用户session。这是在集群中增加了中间件,代价也不小。
3.用户负载,这是一个偷奸耍滑的方案,通过nginx负载,将同一个用户的请求指向最初登录的那个服务器。

token如何实现身份认证

前面我们说了session方案需要考虑服务扩展问题,那么有没有更好的解决方案呢” />单token续期方案

1.用户登录,服务端返回生成的Jwt,携带必要的信息。
2.用户再次访问时均需要在Authorization Header中携带Jwt。
3.服务端有配置好的token失效时间或者次数,还有重新登录期限。每次登录会记录当前登录时间。
4.用户携带token访问时,服务端根据token失效时间和重新登录期限判断返回对应代码
5.当token有效时,服务端返回对应资源。
6.当token失效时,前端拿到错误代码后重新请求refresh token接口进行token刷新,该接口会返回新的有效token给前端。
7.前端下次请求会携带刷新后的新token访问。
8.当某次访问时,服务端判断token使用时长超过了定义好的登录期限,则返回重新登录错误代码给前端,前端拿到代码后跳转至登录页面。

双token续期方案

1.用户登录返回access_token、refresh_token。
2.用户请求资源时携带access_token。
3.当access_token有效时,返回对应的资源。
4.当服务端校验access_token失效,则返回对应错误代码。
5.前端拿到access_token失效对应的错误代码,发起刷新token请求,本次请求携带之前缓存的refresh_token。
6.服务端拿到refresh_token,判断是否有效,失效则返回重新登录错误代码。
7.前端拿到重新登录错误代码则跳转登录页面。

小结

可以看到,使用token进行身份认证,不仅将服务端的存储压力分摊到了客户端上,并且可以让服务端进行毫无顾及的扩展,除此之外也不存在跨域问题,对于移动端也更加友好,不仅如此,Jwt的加密使得这种方案在安全性上更上一层楼。因此,各位架构师们,这是一种不得不掌握的身份认证方案。
点赞收藏,富婆包养✋✋