JWT开发详解

文章目录

  • 一、JWT理论基础
  • 二、JWT使用实例
    • 2.1 服务端代码
    • 2.2 客户端代码
  • 三、JWT流程

一、JWT理论基础

JSON Web Token(JWT)是一种开放标准(RFC 7519),用于在网络上以紧凑且自包含的方式安全地传输信息。JWT 被设计为在用户和服务之间传递声明信息,以便进行身份验证和授权。该标准定义了一种简洁的、自包含的方法,可以传递使用 JSON 对象进行编码的信息,这些信息可以被验证和信任。

JWT 由三个部分组成:Header、Payload 和 Signature。这三部分通过.符号分隔,并以Base64编码的形式进行表示。

  1. Header(头部):

    • Header 包含了两部分信息,分别是 token 的类型(JWT)和使用的签名算法,例如:
      {"alg": "HS256","typ": "JWT"
      }
      
    • 上述例子表示使用 HMAC SHA-256 算法进行签名。
  2. Payload(负载):

    • Payload 包含了声明(claims)。声明是关于实体(通常是用户)和其他数据的声明。有三种类型的声明:

      • 注册声明(Registered claims): 这些是一组预定义的声明,包括 iss(签发者)、sub(主题)、aud(受众)、exp(过期时间)、nbf(不可用之前的时间)和 iat(发布时间)。
      • 公共声明(Public claims): 可以根据需要定义的声明。
      • 私有声明(Private claims): 用于在同意使用它们的双方之间共享信息。
    • 例如:

      {"sub": "1234567890","name": "John Doe","admin": true
      }
      
  3. Signature(签名):

    • 使用编码的 header、编码的 payload 和一个秘密密钥来创建签名部分。签名用于验证消息在传递过程中是否被篡改。

    • 例如:

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

JWT 的工作流程通常如下:

  1. 用户进行身份验证,并且身份验证成功后,服务器会生成一个包含用户信息的 JWT,并将其返回给用户。
  2. 用户在之后的请求中将 JWT 放入请求的头部(通常是 Authorization 头部)中。
  3. 服务器在接收到请求时,使用之前共享的密钥来验证 JWT 的签名,以确保信息的完整性。
  4. 如果签名验证成功,服务器可以使用 JWT 中的信息进行授权判断。

优势和特点:

  • 简洁性: JWT 使用 JSON 数据格式,具有良好的可读性和编码/解码的便捷性。
  • 自包含: JWT 包含了所有需要的信息,避免了每次请求时都需要查询数据库的开销。
  • 可靠性: JWT 的签名机制保证了消息的完整性,防止了信息被篡改的可能性。
  • 跨域: 可以在不同的域之间进行信息传递,支持跨域应用场景。

需要注意的是,由于 JWT 使用了 Base64 编码,虽然可以在客户端解码查看,但不能修改,因为修改后签名验证将失败。然而,JWT 中的信息仍然是可见的,因此敏感信息应该被妥善处理。

二、JWT使用实例

2.1 服务端代码

编写一个完整的 JWT 项目涉及多个方面,包括用户认证、生成和验证 JWT、路由保护等。下面是一个简单的示例,使用 Node.js 和 Express 框架实现:

首先,确保你已经安装了 Node.js 和 npm。然后,创建一个新目录,执行以下步骤:

  1. 初始化项目:

    npm init -y
    
  2. 安装依赖:

    npm install express jsonwebtoken body-parser
    
  3. 创建一个 server.js 文件:

    const express = require('express');
    const jwt = require('jsonwebtoken');
    const bodyParser = require('body-parser');const app = express();
    const PORT = 3000;
    const SECRET_KEY = 'your_secret_key';app.use(bodyParser.json());// 用户数据库(示例)
    const users = [{ id: 1, username: 'user1', password: 'password1' },{ id: 2, username: 'user2', password: 'password2' },
    ];// 登录路由
    app.post('/login', (req, res) => {const { username, password } = req.body;// 实际项目中应该通过数据库查询验证用户信息const user = users.find((u) => u.username === username && u.password === password);if (user) {// 生成 JWTconst token = jwt.sign({ userId: user.id, username: user.username }, SECRET_KEY, { expiresIn: '1h' });res.json({ token });} else {res.status(401).json({ error: 'Invalid credentials' });}
    });// 保护路由
    app.get('/protected', (req, res) => {const token = req.header('Authorization');if (!token) {return res.status(401).json({ error: 'Unauthorized' });}// 验证 JWTjwt.verify(token, SECRET_KEY, (err, decoded) => {if (err) {return res.status(401).json({ error: 'Invalid token' });}res.json({ message: 'You are authorized!', user: decoded });});
    });app.listen(PORT, () => {console.log(`Server is running on http://localhost:${PORT}`);
    });
    
  4. 运行应用:

    node server.js
    

现在,你的应用将在 http://localhost:3000 上运行。你可以使用 Postman 或其他工具模拟登录请求,然后将生成的 token 用于访问 /protected 路由。

请注意,以上示例是一个简单的演示,实际项目中需要更复杂的用户认证和安全性措施。在生产环境中,你可能需要使用 HTTPS、存储更安全的密钥、使用数据库进行用户验证等。

2.2 客户端代码

客户端部分通常是一个前端应用,可以使用 HTML、CSS、JavaScript(通常使用框架如 React、Vue.js 或 Angular)来实现。在客户端,主要任务包括用户界面的设计、用户登录、JWT 的处理、以及向服务器发起请求等。

以下是一个简单的 HTML、CSS、JavaScript 示例,使用原生 JavaScript 实现:

  1. 创建一个 index.html 文件:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>JWT Demo - Client</title>
</head>
<body><h1>JWT Demo - Client</h1><div id="login-form"><label for="username">Username:</label><input type="text" id="username" required><br><label for="password">Password:</label><input type="password" id="password" required><br><button onclick="login()">Login</button></div><div id="protected-content" style="display: none;"><h2>Protected Content</h2><p id="message"></p></div><script>function login() {const username = document.getElementById('username').value;const password = document.getElementById('password').value;fetch('http://localhost:3000/login', {method: 'POST',headers: {'Content-Type': 'application/json',},body: JSON.stringify({ username, password }),}).then(response => response.json()).then(data => {if (data.token) {// 登录成功,显示保护内容document.getElementById('login-form').style.display = 'none';document.getElementById('protected-content').style.display = 'block';document.getElementById('message').innerText = 'Loading...';// 使用获取的 token 访问受保护的路由fetch('http://localhost:3000/protected', {headers: {'Authorization': data.token,},}).then(response => response.json()).then(protectedData => {document.getElementById('message').innerText = `Welcome, ${protectedData.user.username}!`;}).catch(error => console.error('Error fetching protected content:', error));} else {alert('Invalid credentials');}}).catch(error => console.error('Login error:', error));}</script>
</body>
</html>

这个简单的 HTML 文件包含一个登录表单和一个显示受保护内容的部分。当用户成功登录后,它会获取 JWT,并使用该令牌向服务器发起受保护路由的请求。

请注意,这只是一个基础示例,实际项目中应该考虑更多的安全性和用户体验问题。前端应用通常会使用一些框架,以更好地组织和管理代码。

三、JWT流程

以下是一个使用 Mermaid 语法绘制的简单 JWT 流程图:

1. 提供用户名和密码
2. 验证用户信息
3. 发送JWT
4. 包含JWT的请求
5. 验证JWT
6. 返回受保护资源
用户
服务器
生成JWT
服务器
授权访问

这个流程图简要描述了 JWT 的使用过程:

  1. 用户提供用户名和密码。
  2. 服务器验证用户信息。
  3. 如果验证成功,服务器生成 JWT。
  4. 服务器将包含 JWT 的响应发送给用户。
  5. 用户在后续请求中包含 JWT。
  6. 服务器验证 JWT 并授权用户访问受保护资源。

请注意,这只是一个高层次的概述,实际流程可能因应用场景而异,例如,在生成 JWT 时可能涉及更多的步骤,而在验证 JWT 时可能涉及更多的安全性检查。

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

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

相关文章

【Android】如何使用模拟器调试安卓项目

1、电脑安装逍遥模拟器&#xff0c;用来跑安卓项目。安装好模拟器之后&#xff0c;直接起安卓项目&#xff0c;自动会在选择设备处显示 2、如果前端是安卓后端是其他语言的话&#xff0c;这种前后端分离的模式&#xff0c;需要监听端口&#xff0c;原因是运行安卓和后端编译器都…

NC65 如何设置现金流量明细查询的查询框中核算账簿可多选??

NC65 如何设置现金流量明细查询的查询框中核算账簿可多选&#xff1f;&#xff1f; NC65 如何设置现金流量明细查询的查询框中核算账簿可多选&#xff1f;&#xff1f;效果如下图 解决方案二开&#xff0c;即在 nc.ui.gl.cashflowcase.CashFlowDetailQueryUI 的 onButtonQuer…

安装银河麒麟linux系统docker(docker-compose)环境,注意事项(一定能解决,有环境资源)

1&#xff1a;安装docker环境必须使用麒麟的版本如下 2&#xff1a;使用docker-compse up -d启动容器遇到的文件 故障1&#xff1a;如果运行docker-compose up 报“Cannot create redo log files because data files are corrupt or the database was not shut down cleanly a…

使用docker部署nacos分布式集群

本文目的 在服务器中部署nacos集群&#xff0c;并连接外置数据库关于外置的mysql部署和单例nacos如何部署请看下面的两个链接 如何使用docker部署mysql docker部署容器化mysql5.7-CSDN博客 如何使用docker部署nacos 容器化部署Nacos&#xff1a;从环境准备到启动-CSDN博客…

导航守卫有哪三种?

导航守卫主要分为三种&#xff1a; 全局前置守卫&#xff1a;使用 router.beforeEach 注册&#xff0c;作用是在路由切换开始前进行拦截和处理&#xff0c;可以用来进行一些全局的权限校验、登录状态检查等操作。 全局解析守卫&#xff1a;使用 beforeResolve 注册&#xff0c…

mfc140u.dll丢失的解决方法,以及针对每个解决mfc140u.dll丢失办法的优缺点

在使用电脑的过程中&#xff0c;有时会遇到一些与动态链接库文件&#xff08;DLL&#xff09;相关的错误。其中&#xff0c;mfc140u.dll丢失是一种常见的问题&#xff0c;它可能导致应用程序无法正常运行。在本文中&#xff0c;我们将探讨关于mfc140u.dll丢失的解决办法&#x…

WordPress主题WoodMart v7.3.2 WooCommerce主题和谐汉化版下载

WordPress主题WoodMart v7.3.2 WooCommerce主题和谐汉化版下载 WoodMart是一款出色的WooCommerce商店主题&#xff0c;它不仅提供强大的电子商务功能&#xff0c;还与流行的Elementor页面编辑器插件完美兼容。 主题文件在WoodMart Theme/woodmart.7.3.2.zip&#xff0c;核心在P…

目标检测YOLO实战应用案例100讲-基于机器视觉的水稻病虫害监测预警

目录 前言 国内外研究现状 国外研究现状 国内研究现状 2 相关理论与技术

利用 Pandoc + ChatGPT 优雅地润色论文,并保持 Word 公式格式:Pandoc将Word和LaTeX文件互相转化

论文润色完美解决方案&#xff1a;Pandoc 与 ChatGPT 的强强联合 写在最前面其他说明 一、通过 Pandoc 将 Word 转换为 LaTeX 的完整指南步骤 1: 安装 PandocWindows:macOS:Linux: 步骤 2: 准备 Word 文档步骤 3: 转换文档步骤 4: 检查并调整输出步骤 5: 编译 LaTeX 文档总结 二…

使用 DFS 轻松求解数独难题(C++ 的一个简单实现)

起因 都说懒惰是第一生产力&#xff0c;最近在玩数独游戏的时候&#xff0c;总会遇到拆解数独比较复杂的情况&#xff0c;就想着自己写个代码解题&#xff0c;解放双手。所以很快就写了一个简单的代码求解经典数独。拿来跑了几个最高难度的数独发现确实很爽&#xff01;虽说是…

Ubuntu 22.04安装Rust编译环境并且测试

我参考的博客是《Rust使用国内Crates 源、 rustup源 |字节跳动新的 Rust 镜像源以及安装rust》 lsb_release -r看到操作系统版本是22.04,uname -r看到内核版本是uname -r。 sudo apt install -y gcc先安装gcc&#xff0c;要是结果给我的一样的话&#xff0c;那么就是安装好了…

【SpringBoot篇】分页查询 | 扩展SpringMvc的消息转换器

文章目录 &#x1f6f8;什么是分页查询&#x1f339;代码实现⭐问题&#x1f384;解决方法 做了几个项目&#xff0c;发现在这几个项目里面&#xff0c;都实现了分页查询效果&#xff0c;所以就总结一下&#xff0c;方便学习 我们基于黑马程序员的苍穹外卖来讲解分页查询的要点…

go-zero对数据库的操作

一、go-zerro中结合gorm来操作mysql数据库 1、这里我这就直接结合gorm-gen的方式来实现数据库操作,关于gorm-gen可以参考官网 2、创建一个数据库&#xff0c;并且创建一个表 -- ------------------------ -- 用户表 -- ------------------------ DROP TABLE IF EXISTS user; C…

Java中如何通过路径表达式找值:XPath和JsonPath以及SpEL详解及对比

大家好&#xff0c;我是G探险者。 我们编程时&#xff0c;在前后端数据交互和传输过程中&#xff0c;往往需要对报文中的某个字段或者某个标签的值进行解析读取&#xff0c;报文通常是以json或者xml作为数据交换格式&#xff0c;而json和xml这两种格式的报文结构都是具备一定的…

docker容器自启动

场景 当服务器关机重启后&#xff0c;docker容器每次都要去docker start 容器id 怎么可以下次让它自启动呢&#xff1f; 解决 先 # docker ps -a 查到之前启动过的容器id # docker update --restartalways 容器id重启后&#xff0c;reboot&#xff0c;就不用再单独去启动容…

string类的总结

目录 1.为什么要学习string类 2.string的标准库 3.string类的常用接口说明 1.string类对象的常见构造 2.string类对象的容量操作 3.string类对象的3种遍历方法 3.1 [ ] 下标 3.2 基于范围的for循环 3.3 迭代器 4 string类对象的元素访问 4.1 operator[]&#xff1a; 4.…

【洛谷 P3853】[TJOI2007] 路标设置 题解(二分答案+循环)

[TJOI2007] 路标设置 题目背景 B 市和 T 市之间有一条长长的高速公路&#xff0c;这条公路的某些地方设有路标&#xff0c;但是大家都感觉路标设得太少了&#xff0c;相邻两个路标之间往往隔着相当长的一段距离。为了便于研究这个问题&#xff0c;我们把公路上相邻路标的最大…

目标检测—YOLO系列(二 ) 全面解读复现YOLOv1 PyTorch

精读论文 前言 从这篇开始&#xff0c;我们将进入YOLO的学习。YOLO是目前比较流行的目标检测算法&#xff0c;速度快且结构简单&#xff0c;其他的目标检测算法如RCNN系列&#xff0c;以后有时间的话再介绍。 本文主要介绍的是YOLOV1&#xff0c;这是由以Joseph Redmon为首的…

交通 | 神奇动物在哪里?Operations Research经典文章

论文作者&#xff1a;Robert G. Haight, Charles S. Revelle, Stephanie A. Snyder​ 论文原文&#xff1a;Robert G. Haight, Charles S. Revelle, Stephanie A. Snyder, (2000) An Integer Optimization Approach to a Probabilistic Reserve Site Selection Problem. Operat…

C语言比较运算符

常用比较运算符 常用的比较运算符有&#xff1a; ! < > < > 运算符术语示例表示结果相等于2 10!不等于2 ! 11<小于2 < 10>大于2 > 11<小等于2 < 10>大于等于2 > 11 比较运算符注意事项 C语言的比较运算中&#xff0c;真用数字 1 表示…