为了账号安全,请及时绑定邮箱和手机立即绑定

从零开始学习JWT:入门教程

标签:
安全 API
概述

本文详细介绍了JWT的基本概念、特点、工作原理及其组成部分,并探讨了JWT在实际项目中的应用和常见问题的解决方案。

JWT简介与基本概念

JWT(JSON Web Token)是一种开放标准,用于在各方之间安全地传输信息。JWT可以被编码成一个紧凑的URL安全的字符串,以便在浏览器环境下轻松地通过HTTP请求头或URL参数传递。

什么是JWT

JSON Web Token是一种安全的、基于标准的、自包含的令牌格式,用于在两个系统之间传递声明。JWT通常用于身份验证和授权,提供了一种无状态、轻量级的身份验证机制。

JWT的特点与优势

  1. 紧凑且自包含:JWT通常使用Base64编码,占用的网络流量较小。它是一个紧凑的URL安全的令牌,可以包含声明。
  2. 无状态:服务器不需要存储JWT,使得系统可以更易于扩展和维护。
  3. 可扩展:JWT的负载部分可以自定义,可以根据实际需求添加更多的信息。
  4. 安全性:JWT使用HMAC算法或RSA公钥/私钥对进行签名,确保传递的信息不会被篡改。

JWT的工作原理简述

JWT的工作原理如下:

  1. 生成JWT:客户端向服务器请求一个JWT。
  2. 验证JWT:服务器生成JWT并签名,然后将JWT返回给客户端。
  3. 传递JWT:客户端在每次请求时都需要包含这个JWT,通常是在HTTP请求头中。
  4. 验证JWT:服务器在收到请求后,会验证JWT是否有效,并根据令牌中的声明执行相应的操作。
JWT的组成部分

JWT由三部分组成,分别通过.符号连接。这三部分分别是Header、Payload和Signature。

Header(头部)

Header通常包含两个字段:“alg”和“typ”。其中,“alg”表示使用的算法类型,常见的有HS256(HMAC SHA-256)和RS256(RSA SHA-256)。而“typ”则指定了令牌类型,对于JWT来说固定为“JWT”。

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

Payload(负载)

Payload部分包含了被传输的数据。这些数据被称为“声明”,可以分为三类:

  • 注册声明:这些是JWT标准中定义的一组预期的声明,例如“iss”(JWT的发行者)、“sub”(JWT主体)、“aud”(接收主体)、“exp”(过期时间)。
  • 公共声明:这些并不是JWT规范中的预定义声明,但可以包含任何其他自定义声明,例如用户ID或角色。
  • 私人声明:这些声明不应用于通过跨信任域的JSON Web令牌交换,主要用于JWT的特定应用程序的上下文或情况。
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

Signature(签名)

签名是用Header中指定的算法,基于Base64编码后的Header和Payload生成的,目标是确保JWT没有被篡改,并验证该JWT是否来自可信的源。

示例代码

生成Header和Payload的字符串并进行Base64编码的示例代码:

const header = {
  alg: "HS256",
  typ: "JWT"
};
const payload = {
  sub: "1234567890",
  name: "John Doe",
  iat: 1516239022
};

const base64Header = btoa(JSON.stringify(header));
const base64Payload = btoa(JSON.stringify(payload));

console.log(base64Header);
console.log(base64Payload);
如何生成JWT

选择合适的库或工具

生成JWT时,可以使用多种语言的库。其中一些常用语言的库如下:

  • Node.jsjsonwebtoken
  • Pythonpyjwt
  • Javajjwt

编写生成JWT的代码示例

下面以Node.js为例,使用jsonwebtoken库生成一个JWT。

安装jsonwebtoken

npm install jsonwebtoken

生成JWT的示例代码

const jwt = require('jsonwebtoken');

// 密钥
const secret = 'your256bitsecretkey';

// 负载信息
const payload = {
  user: 'John Doe',
  id: '1234567890'
};

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

console.log(token);

解释代码中的重要参数

  • payload:携带的具体信息,是一个包含用户信息的对象。
  • secret:用于生成签名的密钥,必须保持机密。
  • expiresIn:JWT的有效期,格式可以是秒数或时间格式字符串(如1h, 1d)。

生成的JWT将是一个字符串,类似于eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiSm9obiBEb2UiLCJpZCI6IjEyMzQ1Njc4OTAifQ.oGBzKQhG7f9044sH7gW54hPmT4f0c742J643h3A1F7

JWT的验证与解析

验证JWT的必要性

为了保证JWT的安全性,必须在每次收到JWT时进行验证。验证过程包括检查JWT的有效性(如过期时间)、确保JWT未被篡改,并且JWT是由可信源生成的。

解析JWT的步骤

  1. 解析JWT:将JWT字符串分割成三部分,分别是Header、Payload和Signature。
  2. 验证签名:利用Header中指定的算法,使用Base64编码后的Header和Payload生成一个签名,并与实际接收到的Signature进行比较,确保JWT未被篡改。

验证JWT的示例代码

下面以Node.js为例,使用jsonwebtoken库验证一个JWT。

const jwt = require('jsonwebtoken');

// 密钥
const secret = 'your256bitsecretkey';

// JWT字符串
const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiSm9obiBEb2UiLCJpZCI6IjEyMzQ1Njc4OTAifQ.oGBzKQhG7f9044sH7gW54hPmT4f0c742J643h3A1F7';

// 验证JWT
try {
  const decoded = jwt.verify(token, secret);
  console.log('JWT有效,解码后的信息:', decoded);
} catch (error) {
  console.error('JWT无效或已过期', error.message);
}

解释代码中的重要参数

  • token:需要验证的JWT字符串。
  • secret:用于验证签名的密钥,必须与生成JWT时使用的密钥一致。
JWT在实际项目中的应用

JWT在用户认证中的应用

在用户认证场景中,服务器在用户登录成功后生成一个JWT,并返回给客户端。客户端在后续的请求中携带这个JWT,服务器在每次收到请求时验证JWT的有效性,从而确认用户的合法性。

JWT在接口权限控制中的作用

对于需要验证权限的接口,可以通过JWT中的声明来判断用户是否有权限访问该接口。例如,可以将用户的权限等级、角色等信息包含在JWT的负载中,服务器在验证JWT时同时检查这些声明。

JWT在前后端通信中的应用

前后端可以通过JWT来实现无状态通信。前端在接收到JWT后不需要再保存用户状态,只需每次请求时携带JWT即可。后端在验证JWT时,根据JWT中的用户信息执行相应的逻辑。

常见问题与解决方案

JWT过期时间设置

JWT的过期时间需要根据实际需求确定。例如,用户登录后可以设置JWT的有效期为24小时,这样用户在24小时内不需要重新登录。

示例代码:

const token = jwt.sign(payload, secret, { expiresIn: '24h' });

如何处理JWT被篡改的问题

JWT的签名机制能够防止JWT被篡改。当JWT被修改时,生成的签名将与实际的Signature不匹配,从而导致验证失败。

JWT的存储与安全性建议

JWT可以存储在Cookie、LocalStorage或SessionStorage中。选择合适的存储方式需要注意以下几点:

  • Cookie:可以设置HttpOnly属性,防止前端JavaScript直接读取,提供一定的安全性。
  • LocalStorage或SessionStorage:方便前端读取和操作,但需要谨慎处理安全性问题。
  • 安全性建议:避免将JWT存储在前端,如果必须存储在前端,考虑使用HttpOnly Cookie或Service Worker。

通过上述方式,可以确保JWT的使用更加安全可靠。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消