IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 用户登录和权限认证之 —— JWT -> 正文阅读

[系统运维]用户登录和权限认证之 —— JWT

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


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 中就是用户的各种信息。在最后两行多了两个字段:expiat

    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,这一点也可以去深入的了解一下。

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-12-02 17:10:50  更:2021-12-02 17:11:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 2:30:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码