如何实现jwt鉴权机制之详解

news2025/7/30 12:02:16

在这里插入图片描述

jwt鉴权

  • 一是什么
    • header
    • payload
    • Signature
  • 二、如何实现
    • 生成 token
    • 校验token
  • 三、优缺点
    • 优点:
    • 缺点:

一是什么

JWT(JSON Web Token),本质就是一个字符串书写规范,如下图,作用是用来在用户和服务器之间传递安全可靠的信息
在这里插入图片描述
在目前前后端分离的开发过程中,使用token鉴权机制用于身份验证是最常见的方案,流程如下:

  • 服务器当验证用户账号和密码正确的时候,给用户颁发一个令牌,这个令牌作为后续用户访问一些接口的凭证
  • 后续访问会根据这个令牌判断用户时候有权限进行访问

Token,分成了三部分,头部(Header)、载荷(Payload)、签名(Signature),并以.进行拼接。其中头部和载荷都是以JSON格式存放数据,只是进行了编码
在这里插入图片描述

header

每个JWT都会带有头部信息,这里主要声明使用的算法。声明算法的字段名为alg,同时还有一个typ的字段,默认JWT即可。以下示例中算法为HS256

{  "alg": "HS256",  "typ": "JWT" } 

因为JWT是字符串,所以我们还需要对以上内容进行Base64编码,编码后字符串如下:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9        

payload

载荷即消息体,这里会存放实际的内容,也就是Token的数据声明,例如用户的idname,默认情况下也会携带令牌的签发时间iat,通过还可以设置过期时间,如下:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

同样进行Base64编码后,字符串如下:

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

Signature

签名是对头部和载荷内容进行签名,一般情况,设置一个secretKey,对前两个的结果进行 HMACSHA25算法,公式如下:

Signature = HMACSHA256(base64Url(header)+.+base64Url(payload),secretKey)

一旦前面两部分数据被篡改,只要服务器加密用的密钥没有泄露,得到的签名肯定和之前的签名不一致

二、如何实现

Token的使用分成了两部分:

  • 生成token:登录成功的时候,颁发token
  • 验证token:访问某些资源或者接口时,验证token

生成 token

借助第三方库jsonwebtoken,通过jsonwebtoken sign 方法生成一个 token

  • 第一个参数指的是 Payload

  • 第二个是秘钥,服务端特有

  • 第三个参数是 option,可以定义 token 过期时间

const crypto = require("crypto"),
  jwt = require("jsonwebtoken");
// TODO:使用数据库
// 这里应该是用数据库存储,这里只是演示用
let userList = [];

class UserController {
  // 用户登录
  static async login(ctx) {
    const data = ctx.request.body;
    if (!data.name || !data.password) {
      return ctx.body = {
        code: "000002", 
        message: "参数不合法"
      }
    }
    const result = userList.find(item => item.name === data.name && item.password === crypto.createHash('md5').update(data.password).digest('hex'))
    if (result) {
      // 生成token
      const token = jwt.sign(  
        {
          name: result.name
        },
        "test_token", // secret
        { expiresIn: 60 * 60 } // 过期时间:60 * 60 s
      );
      return ctx.body = {
        code: "0",
        message: "登录成功",
        data: {
          token
        }
      };
    } else {
      return ctx.body = {
        code: "000002",
        message: "用户名或密码错误"
      };
    }
  }
}

module.exports = UserController;

在前端接收到token后,一般情况会通过localStorage进行缓存,然后将token放到HTTP请求头Authorization 中,关于Authorization 的设置,前面要加上 Bearer ,注意后面带有空格

axios.interceptors.request.use(config => {
  const token = localStorage.getItem('token');
  config.headers.common['Authorization'] = 'Bearer ' + token; // 留意这里的 Authorization
  return config;
})

校验token

使用 koa-jwt 中间件进行验证,方式比较简单

/ 注意:放在路由前面
app.use(koajwt({
  secret: 'test_token'
}).unless({ // 配置白名单
  path: [/\/api\/register/, /\/api\/login/]
}))
  • secret 必须和 sign 时候保持一致
  • 可以通过 unless 配置接口白名单,也就是哪些 URL 可以不用经过校验,像登陆/注册都可以不用校验
  • 校验的中间件需要放在需要校验的路由前面,无法对前面的 URL 进行校验

获取token用户的信息方法如下:

router.get('/api/userInfo',async (ctx,next) =>{    const authorization =  ctx.header.authorization // 获取jwt    const token = authorization.replace('Beraer ','')    const result = jwt.verify(token,'test_token')    ctx.body = result

注意:上述的HMA256加密算法为单秘钥的形式,一旦泄露后果非常的危险

在分布式系统中,每个子系统都要获取到秘钥,那么这个子系统根据该秘钥可以发布和验证令牌,但有些服务器只需要验证令牌

这时候可以采用非对称加密,利用私钥发布令牌公钥验证令牌,加密算法可以选择RS256

三、优缺点

优点:

  • json具有通用性,所以可以跨语言
  • 组成简单,字节占用小,便于传输
  • 服务端无需保存会话信息,很容易进行水平扩展
  • 一处生成,多处使用,可以在分布式系统中,解决单点登录问题
  • 可防护CSRF攻击

缺点:

  • payload部分仅仅是进行简单编码,所以只能用于存储逻辑必需的非敏感信息
  • 需要保护好加密密钥,一旦泄露后果不堪设想
  • 为避免token被劫持,最好使用https协议

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/394536.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Wannacrypt蠕虫老树开花?又见Wannacrypt

Wannacrypt蠕虫是一个在2017年就出现的远古毒株,其利用永恒之蓝漏洞降维打击用户服务器,而后进行扩散勒索,曾经一度风靡全球,可谓是闻者伤心,听着落泪,因为这玩意解密是不可能 解密的。 而2023年的今天&am…

MCM 箱模型建模方法及大气 O3 来源解析实用干货

OBM 箱模型可用于模拟光化学污染的发生、演变过程,研究臭氧的生成机制和进行敏感性分析,探讨前体物的排放对光化学污染的影响。箱模型通常由化学机理、物理过程、初始条件、输入和输出模块构成,化学机理是其核心部分。MCM (Master Chemical M…

【每天学习一点新知识】JNDI注入

什么是JNDIJNDI是Java的一种API,为我们提供了查找和访问各种命名和目录服务的通用统一的接口。通过JNDI统一接口我们可以来访问各种不同类型的服务,例如远程方法调用(RMI),通用对象请求代理体系结构(CORBA&…

Qt QTreeView简单使用

QT-QTreeView使用方法 QTreeView: 用于显示树状结构数据,适用于树状结构数据的操作。 一、初始化 ​ 利用QStandardlternModel来初始化数据,标准的基于项数据的数据模型类, 每个项数据可以是任何数据类型。 // 初始化model QStandardItem…

工作实战之拦截器模式

目录 前言 一、结构中包含的角色 二、拦截器使用 1.拦截器角色 a.自定义拦截器UserValidateInterceptor,UserUpdateInterceptor,UserEditNameInterceptor b.拦截器配置者UserInterceptorChainConfigure,任意组装拦截器顺序 c.拦截器管理者…

VM安装FydeOS16.0

准备工作 1、已安装VMware Workstation虚拟机; 2、下载好系统文件; 3、打开VM、新建虚拟机; 一、下载 https://fydeos.com/download/vm 我选择的镜像1。等下载完成,我这感觉下载速度不快,通过onedrive下载要快。 …

Jfrog 搭建本地maven仓库以及上传Android库

Jfrog 下载 安装包下载地址:Download Artifactory OSS | JFrog 如果是想下载之前的版本,可以点击上面的Get code source ,如果是最新版本,直接点下面的下载就好。下面以Linux安装为例。 Jfrog安装 对于Linux而言,其实…

Java泛型深入

一. 泛型的概述和优势 泛型概述 泛型&#xff1a;是JDK5中引入的特性&#xff0c;可以在编译阶段约束操作的数据类型&#xff0c;并进行检查。泛型的格式&#xff1a;<数据类型>&#xff0c;注意&#xff1a;泛型只能支持引用数据类型。集合体系的全部接口和实现类都是…

Java刷题-----蓝桥杯省赛JavaC组第十二届(第二场)4-------------6

4、格点题目本题总分&#xff1a;10 分问题描述如果一个点 ( x , y ) 的两维坐标都是整数&#xff0c;即 x ∈ Z 且 y ∈ Z &#xff0c;则称这个点为一个格点。如果一个点 ( x , y ) 的两维坐标都是正数&#xff0c;即 x > 0 且 y > 0 &#xff0c;则称这个点在第一象限…

浅谈 Nodejs原型链污染

一直在做php的题目&#xff0c;对其它语言做的很少。刚好在西湖论剑2022复现时&#xff0c;遇到了一道原型链污染的题目&#xff0c;借此机会开始简单学习一下 Nodejs的洞 p&#x1f402;讲解的十分清楚&#xff0c;因此下面举例子就直接用p&#x1f402;的例子进行解释了 目…

SNMP学习和测试

学习 &#xff08;1&#xff09;SNMP是简单网络管理协议&#xff0c;但是多么晦涩我就不说了。 &#xff08;2&#xff09;SNMP工作在应用层&#xff0c;也就是通过socket实现的&#xff0c;基于UDP&#xff0c;端口161和162&#xff0c;161是用于和网管通信的端口&#xff0…

NYUv2生成边界GT(1)

看了cityscape和NYUv2生成边界GT的代码后&#xff0c;因为自己使用的是NYUv2数据集&#xff0c;所以需要对自己的数据集进行处理。CASENet生成边界GT所使用的代码是MATLAB&#xff0c;所以又重新看了一下MATLAB的代码&#xff0c;并进行修改&#xff0c;生成了自己的边界代码。…

Chrome开发使用技巧总结

Chrome一个程序员开发神器&#xff0c;但是好多猿子们不会或者没有正确使用。今天教大家如何利用它快速高效的开发调试工作。代码格式化有很多css/js的代码都会被 minify 掉&#xff0c;你可以点击代码窗口左下角的那个 { } 标签&#xff0c;chrome会帮你给格式化掉。强制DOM状…

基于同步整流技术的Buck变换器研究

基于同步整流技术的Buck变换器研究 摘要 B u c k 变换器作为一种基本的开关电源变换器&#xff0c;在电力变换场合具有广泛的应用。 为解决 B u c k 变换器工作在电感电流连续状态下&#xff0c;续流二极管关断时存在较大的反向电流过冲问题&#xff0c;采用了同步整流技术。…

Spark高手之路2—Spark安装配置

文章目录Spark 运行环境一、Local 模式1. 下载压缩包2.上传到服务器3. 解压4. 启动 Local 环境5. 命令行工具6. 退出本地模式7. 提交应用二、Standalone 模式1. 解压2. 修改配置文件1&#xff09;进入解压缩后路径的 conf 目录&#xff0c;复制 workers.template 文件为 worker…

人人都学会APP开发 提高就业竞争力 简单实用APP应用 安卓浏览器APP 企业内部通用APP制作 制造业通用APP

安卓从2009年开始流程于手机、平板&#xff0c;已经是不争的非常强大生产力工具&#xff0c;更为社会创造非常高的价值&#xff0c;现在已经是202X年&#xff0c;已经十几年的发展&#xff0c;安卓平台已经无所不在。因此建议人人都学学APP制作&#xff0c;简易入门&#xff0c…

JavaSe第6次笔记

1.不建议使用c语言的数组的表示方法。 2.二维数组表示方法 3.数组整体初始化时&#xff0c;只能在定义时初始化。 int[] array; array new int[]{1, 2}; 4. boolean类型数组&#xff0c;默认值是false&#xff0c;String类型数组&#xff0c;默认是null&#xff0c;其它是…

CHAPTER 2 目录及文件

目录及文件1 目录1.1 目录结构1.2 核心目录2 文件2.1 /etc/中的文件2.1.1 修改主机名(/etc/hostname)2.1.2 网卡配置文件2.1.3 开机自启动配置文件(/etc/rc.local)2.1.4 /etc/motd和/etc/issue2.2 /var/中的文件2.3 /proc/中的文件2.3.1 CPU信息(lscpu)3 文件类型3.1 类型说明3…

Golang中GC和三色屏障机制【Golang面试必考】

文章目录Go v1.3 标记—清楚(mark and sweep)方法Go V1.5 三色标记法三色标记过程无STW的问题强弱三色不变式插入写屏障Go V1.8的三色标记法混合写屏障机制混合写屏障场景场景1:对象被一个堆对象删除引用&#xff0c;成为栈对象的下游场景2:对象被一个栈对象删除引用&#xff0…

PyQt 做美*女GIF设置桌面,每天都很爱~

人生苦短&#xff0c;我用python 要说程序员工作的最大压力不是来自于工作本身&#xff0c; 而是来自于需要不断学习才能更好地完成工作&#xff0c; 因为程序员工作中面对的编程语言是在不断更新的&#xff0c; 同时还要学习熟悉其他语言来提升竞争力… 好了&#xff0c;学习…