栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

用户登录和权限认证之 —— JWT

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

用户登录和权限认证之 —— JWT

这里我会讲解 web 前端常用的用户登录和权限认证的方法 —— JWT,有错误希望指正

文章目录
  • 1、cookie + Session
    • ① 概述
    • ② 流程图
    • ③ 校验步骤
    • ④ 存在的问题
  • 2、JWT
    • ① 流程图
    • ② 校验步骤
    • ③ 解读 token 中存储的内容
    • ④ 对 Swagger 一个功能的补充
  • 3、总结


1、cookie + Session

       在讲解 JWT 之前,我先介绍一下最简单的用户登录和权限认证方式:cookie + Session

① 概述

       HTTP 是一种无状态的协议,客户端每次发送请求时,首先要和服务器端建立一个连接,在请求完成后又会断开这个连接。这种方式可以节省传输时占用的连接资源,但同时也存在一个问题:每次请求都是独立的,服务器端无法判断本次请求和上一次请求是否来自同一个用户,进而也就无法判断用户的登录状态。

注意:上面提到 HTTP,是无状态的,但是 HTTP2 也并不能说是有状态的。 因为 HTTP 是无状态的,所以需要 cookie 来记录一些状态。HTTP2 只是对于复用单一 TCP 连接,但是从服务器角度而言依然需要 cookie 来记录一些状态,因此并不能说 HTTP2 是有状态的。

② 流程图

③ 校验步骤
  1. 第一步,用户登录账号,客户端发送 POST 请求,将用户名和密码发送到服务器。
  2. 第二步,服务器会保存用户对应的 session 数据,并且保存在自己的数据库中(当然也可以保存在客户端的内存中)。
  3. 第三步,服务器返回给客户端 HTTP 200 状态码,这个时候在请求头 header 中,保存了一个 Set-cookie: sessionid 的数据,给用户登录的 cookie设置了一个 session 的 id 值。
  4. 第四步,当客户端要获取用户信息的时候,发送 GET 请求,这个时候会自动携带上 cookie 信息,里面保存的就是 session 的 id 值。
  5. 第五步,当服务器接收到请求的时候,会查看客户端发送的请求中的 cookie 字段,并且查看服务器中是否存在该 session 的数据。
  6. 第六步,当服务器交验完毕后,会产生两种情况:第一种情况就是校验成功,返回给客户端 HTTP 200 状态码和客户端所需要的数据;第二种情况就是校验失败,这个时候会返回给客户端 HTTP 401 状态码,Not authorized。

       可以看出基于 cookie 的身份验证是有状态的,意味着验证记录和会话必须同时保存在服务器端和客户端,服务器端需要跟踪记录 session,并且存在数据库中。同时客户端在 cookie 中要保存对应的 sessionid,作为 session 的唯一标识符(就像身份证一样)。

④ 存在的问题

       这种模式的问题就是其扩展性不好,比如只有一台服务器(单机),这么做是肯定没有问题的;如果是一个服务器集群(多台服务器),就需要 session 数据共享,但是现在 session 只存在一台服务器中,所以需要每一台服务器都都读取到 session。有两种解决方案:

  1. 第一种解决方案是对 session 数据做一个持久化,将要共享的数据放入数据持久层当中,当各种服务器收到请求之后,都向持久层去发送数据,这种方法的优点就是架构清晰;缺点是工程量比较大,而且万一这个持久层中的数据挂了,就会单点失败。
  2. 第二种解决方案是使用基于 token(token base)的解决方案。这种解决方案不同于之前在服务器中要保存信息的特点,而是将信息保存在客户端,之后每次请求都将生成的信息发回到服务器。JWT(Json Web Token) 就是这种解决方案的一个代表。

2、JWT ① 流程图

② 校验步骤
  1. 第一步,用户登录账号,客户端发送 POST 请求,将用户名和密码发送到服务器。
  2. 第二步,服务器会验证用户的登录信息(用户名、密码),校验成功的时候会使用 JWT 算法,生成一个 token (已签名的 token)。
  3. 第三步,服务器返回给客户端 HTTP 200 状态码,并且会将生成的 token 放在请求头中(header),并不能放在请求体(body)中。客户端一般会将接收到的 token 存储在浏览器的 localstorage 或者 sessionstorage 。
  4. 第四步,当客户端之后再向服务器发送请求的时候,都会携带上 token (当然也可以将 token 放在 cookie 中自动发送,但是这样不能跨域发送)。最好的做法是将 token 放在 http 的头信息中的 Authorization 字段中(这是官方文档建议的做法)。
  5. 第五步,当服务器接收到请求的时候,接收到了 token 信息,这时候 JWT 进行反向验证,验证对应的 token 是否正确。
  6. 第六步,当服务器交验完毕后,会产生两种情况:第一种情况就是校验成功,返回给客户端 HTTP 200 状态码和客户端所需要的数据;第二种情况就是校验失败,这个时候会返回给客户端 HTTP 401 状态码,Not authorized。

补充: 如果客户端中的用户退出登录的时候,token 就会在客户端进行销毁(相当于直接把 localstorage
数据清除),这一步与服务器无关。

       上面可以看出,基于 token 的身份验证是没有状态的,也就是服务器不需要记录哪些用户已经登录,或者哪些 JWT 已经被处理。之后前后端每一次通信都会携带上这个 token。服务器通过 token 就可以认定用户的身份,服务器也就变成无状态的了。这种权限校验模式非常容易实现扩展,这个时候部署多个服务器都是可以的了。

③ 解读 token 中存储的内容
  1. 这里根据我自己做的项目中的一个 swagger 接口(进行用户登录的接口),来讲解一下 token 中存储的数据。调用该接口后,复制其中 token 内的信息。

  2. 然后打开 JWT 官网:https://jwt.io/#debugger-io,将复制的信息粘贴至 Encoded 中,然后右边会通过解码将 token 解析出来。

    2.1 讲解一下右侧 token 解析出来的内容:
    Ⅰ. HEADER:这是一个 JSON 对象,描述 JWT 的元数据。这里面也存储着两个信息:ALGORITHM 和 TOKEN TYPE

    ALGORITHM:即 JSON 对象中的 alg,表示 JWT 通过哪种算法进行加密,下列是 JWT 常用的加密算法

    TOKEN TYPE:即 JSON 对象中的 typ,指定该数据是什么类型,就是 JWT 类型

    Ⅱ. PAYLOAD:这也是一个JSON 对象,用来存放实际需要传递的数据,data 中就是用户的各种信息。在最后两行多了两个字段:exp 和 iat

    exp:这个存储的数字是 token 的过期时间(有效期的截止日期)
    iat:这个存储的数字是 token 什么的发送时间(即 JWT 什么时候生成的)

    Ⅲ. VERIFY SIGNATURE:signature 是对前两个部分的签名,防止数据篡改,这个需要一个指定的密钥 secret,这个密钥只有服务器才知道,不能泄露给用户。

       上面这三块就是 token 的组成内容:HEADER、PAYLOAD、VERIFY SIGNATURE,token 在用户登录的时候就会将其存储在本地,下次再发送数据请求的时候,就需要将 token 加在 header 中一起发送给服务器

④ 对 Swagger 一个功能的补充

       在 Swagger 中,提供了一个功能,可以将 token 永久的保存在 header 中,后续的请求就会自动携带上 token

  1. 点击 Authorize
  2. 输入 Bearer + token(这个需要将下面请求的 token 中复制过来)
  3. 这下测试一下其他的请求接口,看看 token 是否会被自动添加上,如下图,token 会被自动添加上。
3、总结

       其实进行用户登录和权限认证的方式用很多种,这里我主要是详细的对 JWT 做了一个讲解,有兴趣的可以去了解下 SSO 单点登录和 OAuth 第三方登录。
       这里我再抛出一个问题,上面我提到的,将 token 存放于请求头 header 中,而不能存放在请求体 body,这一点也可以去深入的了解一下。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/590940.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号