再谈JWT

news2024/11/20 7:03:13

什么是JWT

JSON Web Token是一个开发标准(RFC 7519),定义了一个紧凑且独立的方式,可以将各方之间的信息作为JSON对象进行安全传输,该信息可以验证和信任,因为是经过数字签名的。

JWT是JSON Web Token的缩写,是一种轻量级的身份验证和授权的标准。

它通过在用户登录后生成一个包含用户信息和过期时间等数据的JSON格式令牌,并将其使用密钥进行加密,然后在之后的请求中将该令牌发送给服务器,服务器可以根据令牌中的信息验证用户身份并进行授权操作。

更多精彩内容,请微信搜索“前端爱好者戳我 查看

JWT部分组成

JWT 由三部分组成,分别是

  • 头部(Header)、
  • 载荷(Payload)
  • 签名(Signature)。

头部通常用于描述 JWT 的元数据,如算法类型、token 类型等信息,采用 Base64 编码。

  • typ:token的类型,这里固定为JWT
  • alg:使用的hash算法,例如 HMAC SHA256 或者 RSA

载荷是 JWT 实际要传输的内容,通过 Base64 编码进行传输。载荷中可以包含各种声明,如用户 ID、角色、权限等信息。

签名用于验证消息的完整性和真实性,可以使用 HMAC 算法或者 RSA 签名算法生成,由头部和载荷一起进行签名,防止 token 被篡改。

Signature = HMACSHA256(base64URLEncode(header) +"." + base64URLEncode(payload), secret)

JWT的优点

JWT的优点包括:

  • 使用简单、
  • 跨平台支持、
  • 可进行自定义扩展等

但也需要注意,在使用JWT时,我们需要在服务器端妥善保管密钥,并根据实际情况设置过期时间,以防止信息泄露和失效等问题。

JWT工作原理

  1. 用户通过用户名和密码等进行身份验证后,服务器端根据验证结果生成一个包含用户信息(如用户ID、角色等)以及其他辅助信息(如过期时间等)的JSON格式的令牌。服务器使用密钥将令牌进行签名,生成一个JWT。
  2. 签名后的JWT可以被发送到客户端,并保存在客户端的缓存、Cookie或本地存储中。
  3. 客户端在后续的请求中,将JWT发送到服务器,以表明其具有相应的授权。
  4. 服务器对JWT进行验证,检查是否为有效签名、是否过期并确保令牌中包含的用户信息可以满足该请求的要求。如果JWT验证通过,则表示用户已被授权执行特定操作。

总体来说,JWT就是一种安全性较高的身份验证和授权方式。它使用了标准的JSON格式进行数据传输,并利用密钥进行加密和签名,能够更好地保护用户信息和防止非法访问。

生成 JWT 示例

头部(Header):

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

载荷(Payload):

{
  "sub": "1234567890",
  "name": "john doe",
  "iat": 1516239022
}

签名(Signature):

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

其中 secret 是用于生成签名的密钥。

最终 JWT Token:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6ImpvaG4gZG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

这个 JWT 将用户 ID、用户名以及 token 的创建时间作为了载荷,使用 HMACSHA256 算法和密钥生成签名。

在应用中,当需要进行身份验证时,可以通过解密 JWT 并验证签名来确定用户的身份和权限。

生成和验证 JWT 的示例

以下是一个用于生成和验证 JWT 的示例代码:

const jwt = require('jsonwebtoken');
const secret = 'mysecret'; // 秘钥,用于签名

// 生成 JWT
const user = { id: 1, name: 'Alice' };
const token = jwt.sign(user, secret, { expiresIn: '1h' });

console.log(token); // 输出生成的 JWT 字符串

// 验证 JWT
jwt.verify(token, secret, (err, decoded) => {
  if (err) {
    console.error(err);
  } else {
    console.log(decoded); // 输出解码后的用户信息
  }
});

在上面的示例中,jsonwebtoken 模块 提供了 signverify 方法用于生成和验证 JWT。

首先在代码中定义了一个秘钥 secret 用于签名,然后通过 jwt.sign 方法将用户信息和秘钥使用指定的算法进行加密,生成一个 JWT 字符串。其中,expiresIn 参数指定了 JWT 的有效期。

接着,在代码中调用 jwt.verify 方法对 JWT 进行验证,如果没有错误则解密 JWT 并输出解码后的用户信息。如果验证失败,则会输出错误信息。

需要注意的是, 在 JWT 的生成和使用过程中,秘钥需要保密,并且只在服务端保存。此外,也需要注意 JWT 的有效期设置,及时更新并过期失效以避免安全问题。

完整示例:用户登录和token验证

let jwt = require('jsonwebtoken')
let Users = require('../model/users')

/**
 * 用户登录
 */
const login = async ctx => {
    let {username,pwd} = ctx.request.body
    
    await Users.findOne({username,pwd}).then(rel=>{
        if(rel){
            let token = jwt.sign({
                username: rel.username,
                _id: rel._id
            },'server-jwt',{
                expiresIn: 3600 * 24 * 7
            })
        
            ctx.body = {
                code: 200,
                msg: '登录成功',
                token
            }
        }else{
            ctx.body = {
                code: 300,
                msg: '用户名或密码错误'
            }
        }
    }).catch(err=>{
        ctx.body = {
            code: 500,
            msg: '登录时出现异常',
            err
        }
    })
} 

/**
 * 验证用户登录
 */
const verify = async ctx => {
    let token = ctx.header.authorization
    token = token.replace('Bearer ','')

    try{
        let result = jwt.verify(token, 'jianshu-server-jwt')
        await Users.findOne({_id:result._id}).then(rel=>{
            if(rel){
                ctx.body = {
                    code: 200,
                    msg: '用户认证成功',
                    user: rel
                }
            }else{
                ctx.body = {
                    code: 500,
                    msg: '用户认证失败'
                }
            }
        }).catch(err=>{
            ctx.body = {
                code: 500,
                msg: '用户认证失败'
            }
        })
    }catch(err) {
        ctx.body = {
            code: 500,
            msg: '用户认证失败'
        }
    }
} 

module.exports = {
    login,
    verify
}

koa 接口如何设置不进行jwt校验

在 Koa 中,可以使用 koa-jwt 这个中间件来进行 JWT 的校验。如果你想在某些接口中不进行 JWT 校验,可以通过以下两种方式来实现:

方式一:忽略单个路由

你可以在某个路由的处理函数中直接跳过 JWT 校验,例如:

router.get('/public', async (ctx, next) => {
  // 这些接口不需要JWT认证,直接通过
  await next();
});

这样,当请求 /public 这个接口时,Koa 将直接调用下一个中间件,而不进行 JWT 校验。

方式二:忽略多个路由

你也可以使用“或”操作符 | 来设置多个路由,从而忽略它们的 JWT 校验。例如:

const jwt = require('koa-jwt');
const { secret } = require('./config');

// 在初始化路由前,加上这段代码,表示 /login 和 /register 路由不进行JWT校验
app.use(jwt({ secret }).unless({ path: [/^\/login/, /^\/register/] }));

这里的 unless 方法是 koa-jwt 提供的一个快捷方法,用于指定哪些路由不需要 JWT 校验。

通常情况下,在初始化路由之前使用这个方法就可以达到忽略 JWT 校验的效果。

每日一课:react常用知识点之一

React 是一个流行的 JavaScript 库,用于构建用户界面。以下是 React 的一些常见知识点:

组件:

组件是 React 中最重要的概念之一,它负责渲染 UI,并处理用户交互。

组件可以嵌套在其他组件中,形成一个层次结构。

组件可以是类组件或函数组件。

React 中的一切都是组件,它是应用程序中的一个独立单元。

组件可以被重用,并且可以嵌套在其他组件中。

React 中的组件有两种类型:

  • 函数式组件和类组件。函数式组件是一个只接收 props 并返回 JSX 的函数,
  • 类组件是一个继承 React.Component 并覆盖 render 方法的 ES6 类。

以下是一个简单的函数式组件的示例:

function Greeting(props) {
  return <h1>Hello, {props.name}!</h1>;
}

这个组件接收一个 props 对象,并使用 props.name 渲染出一个问候语。

以下是一个类组件的示例:

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  handleClick = () => {
    this.setState((prevState) => ({ count: prevState.count + 1 }));
  };

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={this.handleClick}>Click me</button>
      </div>
    );
  }
}

这个组件有一个初始状态 count 等于 0,当点击按钮时,会更新 count 的值并重新渲染组件。

注意,在类组件中,我们使用了一个专门的状态对象来管理组件的状态,而不是直接使用 props 对象。

无论是函数式组件还是类组件,都是 React 中非常重要的概念,需要仔细理解和掌握。

JSX:

JSX 是一种类似 HTML 的语法,用于在 JavaScript 中描述用户界面。

JSX 是一种语法扩展,允许在 JavaScript 代码中嵌入 XML 标签。

React 使用 JSX 来描述组件的外观和功能,最终将其转换为普通的 JavaScript 代码。

通过使用 JSX,我们可以重用现有的 HTML 结构和 CSS 样式,并且能够更加直观地描述组件的结构和内容。

以下是一个简单的 JSX 示例:

const element = <h1>Hello, World!</h1>;

这个代码片段使用了一个

元素来创建一个 React 元素,并将其赋值给了一个变量。在这个例子中,我们使用了类似于 HTML 的语法来描述元素的结构和内容。

在实际开发中,我们可以使用 JSX 来创建任何类型的元素,包括HTML 元素、React 组件、甚至是其他的 JSX 元素。

以下是一个使用 JSX 来创建组件的示例:

function Greeting(props) {
  return <h1>Hello, {props.name}!</h1>;
}

在这个组件中,我们使用了类似于 HTML 的语法来描述组件的结构和内容。同时,我们也可以使用花括号来插入 JavaScript 表达式,以便动态计算需要渲染的内容。

props 和 state:

props 和 state 是组件中最重要的概念。

props 是从父组件传递给子组件的数据,不会改变。

而 state 是组件内部自己管理的状态,可以随时改变。当 state 发生变化时,React 可以自动更新视图。

props 可以是任何类型的 JavaScript 数据,包括字符串、数字、布尔值、数组、对象等。

以下是一个使用 props 的示例:

function Greeting(props) {
  return <h1>Hello, {props.name}!</h1>;
}

在这个例子中,我们定义了一个函数式组件 Greeting,并且将一个名为 name 的 prop 传递给它。

通过这个 prop,我们可以传递任何字符串给 Greeting 组件,并且在组件内部使用它来渲染问候语。

与 props 不同,state 是组件内部定义的可变状态。只有通过修改组件的 state,才能更新组件的视图。

以下是一个带有 state 的类组件的示例:

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  handleClick = () => {
    this.setState((prevState) => ({ count: prevState.count + 1 }));
  };

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={this.handleClick}>Click me</button>
      </div>
    );
  }
}

在这个例子中,我们定义了一个 Counter 组件,并且在其构造函数中初始化了一个状态 count 等于 0。

在按钮的点击事件处理函数中,我们通过调用 setState 方法来更新组件的状态,并且通过重渲染来更新组件的视图。

props 和 state 都是 React 中非常重要的概念,需要仔细理解和掌握。props 用于在组件之间传递数据,而 state 则用于内部管理组件的状态。在实际开发中,我们通常会同时使用 props 和 state 来构建复杂的组件和应用程序。

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

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

相关文章

第39步 深度学习图像识别:Inception V3建模(Tensorflow)

基于WIN10的64位系统演示 一、写在前面 &#xff08;1&#xff09;Inception V1 Inception是一种深度学习模型&#xff0c;也被称为GoogLeNet&#xff0c;因为它是由Google的研究人员开发的。Inception模型的主要特点是它的“网络中的网络”结构&#xff0c;也就是说&#x…

编译原理笔记6:从正规式到词法分析器(3):DFA最小化、词法分析器的构造、Lex 使用示例

目录 从 DFA 到最小 DFA等价可区分划分算法&#xff1a;最小化 DFA 的状态数&#xff08;DFA化简&#xff09;手写 DFA 词法分析器的构造Lex 使用示例 从 DFA 到最小 DFA 关于星闭包的补充&#xff1a;一个语言被认为是所有可能字的子集。所有可能字的集合可以被认为是所有可能…

手机操作系统的沉浮往事(下)

接上篇&#xff1a;手机操作系统的沉浮往事&#xff08;上&#xff09; 2007年&#xff0c;是手机市场发生历史性转折的一年。 这一年的1月9日&#xff0c;在Macworld 2007大会上&#xff0c;史蒂夫乔布斯正式发布了第一代iPhone。 改变人类科技史的一天 iPhone的问世&#xff…

LeetCode - #83 删除排序链表中的重复元素

文章目录 前言1. 描述2. 示例3. 答案关于我们 前言 我们社区陆续会将顾毅&#xff08;Netflix 增长黑客&#xff0c;《iOS 面试之道》作者&#xff0c;ACE 职业健身教练。&#xff09;的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 LeetCode 算法到目前我们已经更新…

收藏 | 14 种免费 GIS 软件

如果你想绘制一幅世界地图&#xff0c;会选择什么GIS软件呢&#xff0c;ArcGIS、GlobalMapper这些都是国外比较出名的商业GIS软件&#xff0c;当然在国内很容易找到可用的版本&#xff0c;但是也可以使用免费的GIS软件完成所有操作。 这些免费的GIS软件为您提供了完成工作的效…

服务的熔断、降级与限流

1、引言 在微服务架构中&#xff0c;根据业务来拆分成一个个的服务&#xff0c;服务与服务之间可以相互调用&#xff08;RPC&#xff09;。为了保证其高可用&#xff0c;单个服务通常会集群部署。由于网络原因或者自身的原因&#xff0c;服务并不能保证100%可用&#xff0c;如果…

基于Python的高校学生学业预警系统的设计与实现

博主介绍&#xff1a;擅长Java、微信小程序、Python、Android等&#xff0c;专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb; 不然下次找不到哟 Java项目精品实战案例…

基于STM32 ARM+FPGA的电能质量分析仪方案(二)软件设计

本部分主要介绍 FPGAARM 控制部分的软件设计。 FPGAARM 控制部分包括 Verilog HDL 硬件描述语言和 C 语言的开发。 FPGA 部分主要控制 AD7606 模数转换、数字三相锁相 环和FFT谐波计算模块、 SDRAM 控制器的设计、 FSMC 接口模块等。 ARM 部分主要完成嵌 入式实时操作系统 …

十个你必须要会的TypeScript技巧

大厂面试题分享 面试题库 前后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 web前端面试题库 VS java后端面试题库大全 1. 泛型的使用 泛型可以让我们编写更具灵活性、可重用性和类型安全性的代码。在 TypeScrip…

SpringBoot中15个常用启动扩展点,你用过几个?

背景 Spring的核心思想就是容器&#xff0c;当容器refresh的时候&#xff0c;外部看上去风平浪静&#xff0c;其实内部则是一片惊涛骇浪&#xff0c;汪洋一片。Springboot更是封装了Spring&#xff0c;遵循约定大于配置&#xff0c;加上自动装配的机制。很多时候我们只要引用了…

P35[10-5]硬件IIC配置+读写MPU6050(软)(此处注意与软件iic区别)

接线图如下: 注:硬件读写iic的连接位置固定,可参考引脚定义表(如下) 声明:I2C1重映射时,有一次更换机会,但是此面包板由于OLED的该引脚无法接线,因此只能接在PB10 PB11的I2C2上 软件iic初始化部分:(此处即可替代掉整个软件iic.c初始化的底层) void MPU6050_Init(vo…

知识变现绝学,3个步骤5个技巧用你的知识盈利?

知识就是生产力。 有的人通过学习各类知识&#xff0c;结果变的更加迷茫&#xff0c;更加没有方向了。 而有的人通过学习各类知识&#xff0c;结果变成了专家&#xff0c;实现了财务自由。 你想知道如何把这生产力去变现呢&#xff1f; 这个时代信息泛滥&#xff0c;人才泛滥…

305 · 矩阵中的最长递增路径

链接&#xff1a;LintCode 炼码 题解&#xff1a;九章算法 - 帮助更多程序员找到好工作&#xff0c;硅谷顶尖IT企业工程师实时在线授课为你传授面试技巧 class Solution { public:/*** param matrix: A matrix* return: An integer.*/class Node {public:int x;int y;int val…

DNDC模型四:土壤碳储量与作物产量、农田减排潜力分析

查看原文>>>双碳目标下DNDC模型建模方法及在土壤碳储量、温室气体排放、农田减排、土地变化、气候变化中的实践应用 由于全球变暖、大气中温室气体浓度逐年增加等问题的出现&#xff0c;“双碳”行动特别是碳中和已经在世界范围形成广泛影响。国家领导人在多次重要会…

遥感影像处理-监督分类

遥感图像分类是图像信息提取的一种方法&#xff0c;是遥感数字图像处理的重要环节&#xff0c;也是遥感应用最广泛的领域之一&#xff0c;其中提取土地利用分类信息也是常见的应用领域。本推文简要介绍了图像分类的原理和方式&#xff0c;并着重介绍了最大似然分类法监督分类在…

分布式事务:XA和Seata的XA模式

大家好&#xff0c;我是方圆。上一篇博客《从2PC和容错共识算法讨论zookeeper中的Create请求》介绍了保证分布式事务提交的两阶段提交协议&#xff0c;而XA是针对两阶段提交提出的接口实现标准&#xff0c;本文则对XA进行介绍。 1. XA XA &#xff08;eXtended Architecture …

第一章 基础算法(三)—— 双指针,位运算,离散化与区间合并

文章目录 双指针位运算离散化区间合并双指针练习题799. 最长连续不重复子序列800. 数组元素的目标和2816. 判断子序列 位运算练习题801. 二进制中1的个数 离散化练习题802. 区间和 区间合并练习题803. 区间合并 为什么直接用y总的板书&#xff1f; 我是懒狗&#xff0c;不想再画…

音乐考级系统python+mysql

目录 废话不多说下面看严谨版不带web界面的&#xff1a; 总结&#xff1a; 写这个博客呢主要是因为之前学校有个简单的课设要做&#xff0c;想着白嫖一个交差的&#xff0c;但是找了一圈没找到合适的能拿来用的&#xff0c;我就下班用了两晚手搓了一个代码。 具体的建表语句…

PCB设计实验|第二周|谐波振荡电路实验|3月6日

目录 实验二 谐波振荡电路实验 一、实验原理 二、实验环境 三、实验结果及分析 四、实验总结 实验二 谐波振荡电路实验 一、实验原理 利用深度正反馈&#xff0c;通过阻容耦合使两个电子器件交替导通与截止&#xff0c;从而自激产生方波输出的振荡器&#xff0c;常用作…

ChatGPT在前,华为盘古Chat在后

国产盘古Chat对话方面堪比GPT-3.5 什么是ChatGPT&#xff1f;简单来说&#xff0c;就是一个能够和人类自然对话的人工智能系统。它可以理解你的语言&#xff0c;回答你的问题&#xff0c;甚至给你提供建议和服务。它不仅可以处理文字&#xff0c;还可以处理图片、视频、音频等…