一步步教你实现JWT认证和授权

news2025/2/28 2:52:54

一步步教你实现JWT认证和授权

  • 前言
  • 一、引入
  • 二、Token认证与JWT认证的关系
  • 三、什么是JWT认证?
  • 四、JWT的组成
    • 1、头部(Header)
    • 2、载荷(Payload)
    • 3、签名(Signature)
  • 五、JWT认证的工作流程
  • 六、代码举例
  • 七、总结



前言

本博主将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识,有兴趣的小伙伴可以关注博主!
也许一个人独行,可以走的很快,但是一群人结伴而行,才能走的更远!

一、引入

我们上篇文章中为大家介绍了token(令牌)认证的认证机制,而在本文,我们要为大家介绍JWT认证(JSON Web Token authentication)。

二、Token认证与JWT认证的关系

大家现在是否感觉压力山大,不仅学习了Cookie认证,Session认证,还学习了一个Token认证,现在又冒出来了个JWT认证,别担心,这个JWT认证并不是什么新颖的认证方式,本质上它就是一种基于Token的身份验证机制,Token认证是一种通用的身份验证方法,我们可以使用不同类型的Token去进行身份验证,而JWT就是其中的一种Token类型。

在这里我们要区分好,上篇文章为大家介绍的Token认证机制是一个广泛的概念,是一种概称,它涵盖了使用不同类型的Token进行身份验证的方法。除了JWT之外,还有其他类型的Token,例如基于时间的令牌(Time-based Tokens)和访问令牌(Access Tokens)。这些Token可以使用不同的格式和验证机制,但它们都是用于验证用户身份并授权访问受保护资源的凭据。

所以搞清了关系之后,接下来进入正文!

三、什么是JWT认证?

JWT认证(JSON Web Token authentication)是一种基于Token的身份验证机制。它使用JSON Web Token(JWT)作为身份验证的凭据,并通过对JWT进行验证来确认用户的身份和授权用户访问受保护的资源。

四、JWT的组成

上文已经提及,JWT只是众多token类型里的其中一种类型,所以关于它的组成,就是我们要学习的重点。

JWT是一种开放标准(RFC 7519),定义了一种紧凑且自包含的方式来表示和传输信息。它由三个部分组成:

  1. 头部(Header):包含描述JWT的元数据和算法信息,例如使用的签名算法。
  2. 载荷(Payload):包含JWT所声明的数据,可以包含用户身份信息、授权信息和其他自定义数据。
  3. 签名(Signature):使用密钥和指定的签名算法对头部和载荷进行签名,以实现数据完整性和验证。

在这里插入图片描述

1、头部(Header)

头部通常包含两个部分:令牌类型(typ)和签名算法(alg)。这些信息用于描述JWT的类型和使用的加密算法。例如,一个典型的头部可以是以下JSON格式:

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

在上面的例子中,"alg"表示签名算法为HMAC SHA-256(HS256),"typ"表示令牌类型为JWT。

2、载荷(Payload)

载荷是JWT的主体部分,包含要传输的数据。载荷可以包含一些预定义的声明(Claims),也可以包含自定义的声明。预定义的声明分为三类:

  • 注册声明(Registered Claims):这些声明是一组预定义的标准声明,包括iss(签发者)、sub(主题)、aud(受众)、exp(过期时间)、nbf(生效时间)和iat(发布时间)等。
  • 公共声明(Public Claims):这些声明是自定义的声明,供使用者自由定义,但建议遵循一定的命名规范,避免冲突。
    私有声明(Private Claims):这些声明也是自定义的声明,但为了避免冲突,建议将其命名为命名空间形式,例如"company_name"。
    以下是一个示例载荷的JSON格式:
{
  "sub": "user123",
  "name": "John Doe",
  "iat": 1629012345
}

在上面的例子中,"sub"表示主题为"user123"的用户,“name"表示用户姓名为"John Doe”,"iat"表示JWT的发布时间为1629012345(UNIX时间戳)。

3、签名(Signature)

签名是JWT的第三部分,用于验证JWT的完整性和真实性。签名通常使用头部和载荷中的数据以及一个密钥来生成。生成签名的过程是对头部和载荷进行编码,然后使用指定的签名算法(如HMAC、RSA等)进行加密。最终生成的签名字符串将附加在JWT的末尾。

签名的示例:

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

在上面的例子中,"header"表示头部的Base64编码字符串,"payload"表示载荷的Base64编码字符串,"secretKey"表示用于生成签名的密钥。

通过将这三个部分使用句点(.)连接起来,即可形成一个完整的JWT:

base64UrlEncode(header) + "." +
base64UrlEncode(payload) + "." +
signature

最终的JWT可以作为身份验证凭据在客户端和服务器之间进行传输,并通过验证签名来验证JWT的真实性和完整性。

当然很多人会疑惑这个token的安全性,JWT是由三部分组成的,以点分开header、payload和signature

  1. header部分声明需要用什么算法来生成签名

  2. payload部分是一些特定的数据,比如有效期之类

  3. 接着header和payload两部分的内容会经由BASE64编码,注意是编码,不是加密,也就是很容易可以解码,虽然JWT不保存在服务器这里,但是服务器需要保存一段密码,这段密码要结合两段编码进行算法运算,最终得到签名信息。这里使用的算法就是刚刚header声明的算法。签名的信息,也就是signature部分了,这样一个完整的最大的JWT就可以发送给客户端了。如果我们修改三个部分,其中一个字符,整个最大JWT都会出错,三个部分是相关联的,因此JWT有一定的安全性。

引用但老师
token是服务器加密的用户信息,服务器将token发给浏览器,浏览器用cookie或storage保存cookie。然后浏览器每次发送请求就带上token,服务器将其解密并确认用户登录。

五、JWT认证的工作流程

JWT认证的工作流程一般涉及以下步骤:

  1. 用户身份验证:
    用户在进行身份验证时,通常会提供标识自己身份的凭据(例如用户名和密码)。服务器需要验证这些凭据的有效性,通常是通过与存储在数据库中的用户凭据进行比对。

  2. JWT的生成:
    如果用户通过身份验证,服务器将生成一个JWT作为身份验证的凭据。生成JWT的过程包括以下步骤:

    • 创建一个包含头部和载荷的JSON对象。
    • 对头部和载荷进行Base64编码,生成JWT的第一部分。
    • 使用服务器上的密钥和指定的签名算法对编码后的头部和载荷进行签名,生成签名。
    • 将签名与编码后的头部和载荷连接起来,生成完整的JWT。
  3. JWT的发送和存储:
    服务器将生成的JWT发送给客户端,通常是通过将JWT作为响应的一部分(例如在HTTP响应的头部或作为响应的一部分)返回给客户端。客户端通常会将JWT存储在本地,例如在浏览器的本地存储或内存中。

  4. 后续请求的身份验证:
    在后续的请求中,客户端将JWT作为身份验证凭据发送给服务器。通常是通过将JWT放置在请求的头部(例如Authorization头部)中或作为请求参数的一部分(例如查询字符串或表单数据)发送给服务器。

  5. JWT的验证和解析:
    服务器在接收到请求后,需要验证JWT的有效性和完整性,以及解析其中的信息。验证和解析的过程包括以下步骤:

    • 从请求中获取JWT。
    • 检查JWT的签名是否有效,以确保JWT未被篡改。
    • 解码JWT的头部和载荷,获取其中的信息。
  6. 用户授权和访问受保护资源:
    服务器通过验证JWT的有效性,并获取到其中的用户身份信息,确认用户的身份。基于用户的身份信息,服务器可以进行授权判断,决定用户是否有权访问请求的资源。如果用户被授权访问资源,服务器将返回相应的数据或执行相应的操作。

整个JWT认证的工作流程是基于无状态的,服务器无需在后端存储会话状态,每个请求都是独立的。JWT作为身份验证凭据,提供了一种简单、安全和可扩展的方式来验证用户身份,并授权用户访问受保护的资源。

在这里插入图片描述

六、代码举例

以下是一个使用Java JWT库(jjwt)的示例代码:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;

public class JWTExample {
    private static final String SECRET_KEY = "yourSecretKey";
    private static final long EXPIRATION_TIME = 86400000; // 24小时

    public static void main(String[] args) {
        // 创建JWT
        String token = createJWT("user123");

        // 验证和解析JWT
        if (validateJWT(token)) {
            String username = parseJWT(token);
            System.out.println("解析到的用户名:" + username);
        } else {
            System.out.println("JWT验证失败");
        }
    }

    public static String createJWT(String username) {
        Date now = new Date();
        Date expiration = new Date(now.getTime() + EXPIRATION_TIME);

        String token = Jwts.builder()
                .setSubject(username)
                .setIssuedAt(now)
                .setExpiration(expiration)
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();

        return token;
    }

    public static boolean validateJWT(String token) {
        try {
            Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static String parseJWT(String token) {
        Jws<Claims> claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
        return claims.getBody().getSubject();
    }
}

在上述示例中,createJWT方法用于创建JWT,其中设置了用户名、签发时间、过期时间,并使用HS256算法进行签名。validateJWT方法用于验证JWT的合法性,通过解析和校验JWT的签名来进行判断。parseJWT方法用于解析JWT并提取其中的用户名信息。

请注意,上述代码中的SECRET_KEY是用于签名和验证JWT的密钥,请确保将其替换为实际的密钥,并妥善保管。另外,示例中设置的过期时间为24小时(86400000毫秒),我们可以根据自己的需求进行调整。

使用这个示例代码,可以创建一个包含用户名信息的JWT,并验证和解析JWT以获取其中的用户名。

七、总结

大家不要把三者想的太复杂

  1. session是诞生并保存在服务器那边的,由服务器主导一切。
  2. cookie这是一种数据载体,把session放在cookie中送到客户端那边,cookie跟随HTTP的每个请求发送出去。
  3. token是诞生在服务器,但保存在浏览器这边的,由客户端主导一切,可以放在cookie或者storage里面,持有token,就像持有令牌一样,可以允许访问服务器。
  4. 服务器验证是前提。cookie保存在客户端,服务器不加密不保存;session保存在客户端,服务器要加密并保存;token保存在客户端,服务器要加密不保存。
  5. Session是一种服务器端的机制,用于存储和管理用户的身份和状态信息,而Cookie是用于在客户端存储Session ID等数据的机制。Token是一种轻量级的身份验证和授权机制,可以作为无状态的凭据进行传输。Cookie和Token都可以用于在客户端和服务器之间传递身份信息和状态信息,实现身份验证和状态管理的功能。

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

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

相关文章

Matplotlib 多个子图使用一个图例

1 所有子图的图例相同 **利用函数fig.axe.get_legend_handles_labels()得到图的line和label import matplotlib.pyplot as pltfig plt.figure() axes fig.subplots(nrows2, ncols2)for ax in fig.axes:ax.plot([0, 10], [0, 10], labellinear) # 使用最后一个子图的图例 li…

5V升压到12V2A芯片方案

5V升压到12V2A芯片方案&#xff0c;采用了一款2.7V-18V输入&#xff0c;4.5V-18V输出的峰值10A同步升压芯片&#xff0c;内置了MOS&#xff0c;封装为QFN13。 在电子设备中&#xff0c;经常会遇到需要将低电压提升到较高电压的情况。例如&#xff0c;对于一些需要12V电压供电的…

CAD转kml插件acad2kml分享下载

KML&#xff08;Keyhole Markup Language&#xff09;是一种用于描述地理数据的格式&#xff0c;它由Google公司开发并在2008年成为开放标准。KML使用XML语法&#xff0c;可以用于表示地理点、线、多边形、图像覆盖物以及相关属性信息。 KML是一种用于描述地理数据的开放格式&…

多维时序 | MATLAB实现CNN-BiGRU-Attention多变量时间序列预测

多维时序 | MATLAB实现CNN-BiGRU-Attention多变量时间序列预测 目录 多维时序 | MATLAB实现CNN-BiGRU-Attention多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现CNN-BiGRU-Attention多变量时间序列预测&#xff0c;CNN-BiGRU-Attent…

如何高效解决“字符串相乘“问题?

&#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ >&#x1f43b;推荐专栏1: &#x1f354;&#x1f35f;&#x1f32f;C语言初阶 &#x1f43b;推荐专栏2: &#x1f354;&#x1f35f;&#x1f32f;C语言进阶 &#x1f511;个人信条: &#x1f335;知行合一 金句分…

rv1126设置静态ip

开发板配网--------------------------------------------------------------------------------------------- 刚拿到的开发板里面的网络配置大多不可用&#xff0c;此时是无法ping通的&#xff0c;这个时候需要重新修改相关的配置文件&#xff1b; Vi /etc/profile 最后面…

如何将苹果彻底删除视频找回?试试这3种方法

如今是短视频时代&#xff0c;大家通常会使用苹果手机来拍摄视频&#xff0c;以此记录生活中的美好日常。但是大家都知道视频是十分占空间的&#xff0c;这也经常会出现iPhone内存不足&#xff0c;磁盘崩溃的问题。 当遇到iPhone内存不足的情况时&#xff0c;大家往往会选择清…

Failed to execute goal org.apache.maven.plugins

原因&#xff1a; 这个文件D:\java\maven\com\ruoyi\pg-student\maven-metadata-local.xml出了问题 解决&#xff1a; 最简单的直接删除D:\java\maven\com\ruoyi\pg-student\maven-metadata-local.xml重新打包 或者把D:\java\maven\com\ruoyi\pg-student这个目录下所有文件…

【QPSK信号生成】生成正交相移键控信号研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

闪马智能又上榜!

近日&#xff0c;上海市经济和信息化委员会公布了2023年度上半年&#xff08;第30批&#xff09;市级企业技术中心拟认定企业名单。凭借在技术创新方面的突出成就&#xff0c;闪马智能上榜其中。 本次认定由上海市经济和信息化委员会组织开展&#xff0c;综合企业的地位和作用、…

Kubernetes Service 工作原理

本文介绍了 Kubernetes Service 的概念、原理和具体使用。 作者&#xff1a;沈亚军 爱可生研发团队成员&#xff0c;负责公司 DMP 产品的后端开发&#xff0c;爱好太广&#xff0c;三天三夜都说不完&#xff0c;低调低调… 本文来源&#xff1a;原创投稿 爱可生开源社区出品&am…

MAUI+Blazor 如何开启浏览器调试工具

文章目录 前言如何开启调试模式输入快捷键打开浏览器有什么意义&#xff1f; 前言 MAUIBlazor其实就是浏览器套壳&#xff0c;我觉得很有意义&#xff0c;因为现在性能已经不是主要的限制了&#xff0c;很多时候讲究的快速开发。而且MAUIBlazor跨平台的未来感觉实在是太香了。…

基于Gradio的GPT聊天程序

网上很多别人写的&#xff0c;要用账号也不放心。就自己写了一个基于gradio的聊天界面&#xff0c;部署后可以本地运行。 特点&#xff1a; 可以用openai的&#xff0c;也可以用api2d&#xff0c;其他api可以自己测试一下。使用了langchain的库 可以更改模型&#xff0c;会的…

Semantic Kernel 入门系列: Planner 规划器

Semantic Kernel 的一个核心能力就是实现“目标导向”的AI应用。 目标导向 “目标导向”听起来是一个比较高大的词&#xff0c;但是却是实际生活中我们处理问题的基本方法和原则。 顾名思义&#xff0c;这种方法的核心就是先确定目标&#xff0c;然后再寻找实现目标的方法和…

基于R做宏基因组结果的PCoA分析

写在前面 因为公司给的PCA结果效果不佳&#xff0c;决定从中重新挑选部分样本进行再分析 步骤 表格结果预处理 在属水平genus参考原本结果已有的PCA图&#xff0c;尽可能挑选距离较远且聚团的样本 选取不同样本属水平的丰度数据&#xff0c;整理成逗号分隔的csv文件 代码…

Android:自定义沿着曲线轨迹移动

前言 前几天&#xff0c;后台有老铁留言&#xff0c;说有个需求&#xff0c;画两条曲线&#xff0c;中间是一个小球&#xff0c;沿着两条线中间的轨迹从左往右移动&#xff0c;让提供个思路&#xff0c;做为一个极度宠粉的博主&#xff0c;思路不仅要提供&#xff0c;实现方案也…

视图簇 se54 sm34 se54

今天演练了一下 维护视图到视图簇的过程。 se11建表&#xff0c;建表之后 【使用程序】→【表维护生成器】 se54 新建视图簇 对象结构 选中其中一行 字段附属 PS:以上每一行都要设置过去 &#xff0c; 设置完成了 激活 sm34展示

Word转PDF工具哪家安全?推荐好用的文件格式转换工具

Word文档是我们最常见也是最常用的办公软件&#xff0c;想必大家都知道了Word操作起来十分的简单&#xff0c;而且功能也是比较齐全的。随着科技的不断进步&#xff0c;如今也是有越来越多类型的办公文档&#xff0c;PDF就是其中之一&#xff0c;那么word转pdf怎么转?Word转PD…

vue3多页面配置踩坑

vue3实现多页面打包容易&#xff0c;关键是如何实现本地的开发和调试&#xff1f;我们接下来解决如下几个问题&#xff1a; 1 多页面项目的项目结构是怎样的&#xff1f; --public--src---App.vue---main.js---page1. ---App.vue---main.js----home.vue----list.vue---page2.…

申请TikTok海外直播公会的具体流程

截止目前&#xff0c;TikTok的主用户群已经从除中国用户外的亚洲用户群&#xff0c;逐步转变成了以英美欧洲为主体的西方用户群体。TikTok先后在40多个国家的应用商店内排名前列&#xff0c;成为了全球增速最快的短视频APP。接下来的这篇文章就是关于抖音tiktok海外公会申请cmx…