手拉手Springboot整合JWT

环境介绍

技术栈

springboot+mybatis-plus+mysql+java-jwt

软件

版本

mysql

8

IDEA

IntelliJ IDEA 2022.2.1

JDK

1.8

Spring Boot

2.7.13

mybatis-plus

3.5.3.2

Json Web令牌简称JWT

Token是在服务端产生的一串字符串是客户端访问资源接口(AP)时所需要的资源凭证。

 

Token认证流程

1、客户端使用用户名跟密码请求登录,服务端收到请求,验证用户名与密码验证成功后,服务端会签发一个 token并把这个 token发送给客户端,客户端收到 token后,会把它存储起来,比如放在cookie里或者localStorage里

2、客户端每次向服务端请求资源的时候需要带着服务端签发的 token

3、服务端收到请求,然后去验证客户端请求里面带着的 token,如果验证成功就向客户端返回请求的数据

token用户认证是一种服务端无状态的认证方式,服务端不用存放token数据。

用解析 token的计算时间换取 session的存储空间,从而减服务器的力,减少频繁的查询数据库

token完全由应用管理,所以它可以避开同源策略

JWT的使用

JSON Web Token(简称JWT)是一个 token的具体实现方式,是目前最流行的跨域认证解决方案。JWT的原理是:服务器认证以后,生成一个JSON对象,发回给用户。

{

       “name” :”张三”,

       “time”:”2022年10月10日”

}

用户与服务端通信时,都要发回该JSON对象。服务器完全只靠这个对象认定用户身份。

为防止用户篡改数据,服务器在生成对象时,会加上签名

JWT由三个部分组成:Header(头部)、Payload(负载)、Signature(签名)

Header.Payload.Signature

官方描述

Header

JWT头是一个描述JWT元数据的JSON对象,alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256);typ属性表示令牌的类型,JWT令牌统一写为JWT。最后,使用Base64 URL算法将上述JSON对象转换为字符串保存

{

  "alg": "HS256",

  "typ": "JWT"

}

Payload

有效载荷部分,是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。 JWT指定七个默认字段供选择

iss:发行人

exp:到期时间

sub:主题

aud:用户

nbf:在此之前不可用

iat:发布时间

jti:JWT ID用于标识该JWT

Signature

签名哈希部分是对上面两部分数据签名,需要使用base64编码后的header和payload数据,通过指定的算法生成哈希,以确保数据不会被篡改。

加入依赖

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>4.3.0</version>
</dependency>

入门案例

@Test
//生成token
void jwtdemo01(){
     Calendar instance = Calendar.getInstance();
     //instance.add(Calendar.SECOND, 90);
     instance.add(Calendar.DAY_OF_WEEK, 7);

    System.out.println(instance.getTime());
    String token = JWT.create()
            .withClaim("username", "李四")//payload 设置自定义用户名
            .withExpiresAt(instance.getTime())//设置过期时间
            .sign(Algorithm.HMAC256("123"));//设置签名 密钥
    System.out.println(token);
    //"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3MDM5NDcyODMsInVzZXJuYW1lIjoi5p2O5ZubIn0.3onRy8p0G9ojnpA9u5h5ytd8hLZpGMZUyj49LTge5ao"
}

@Test
//验证token
void jwtdemo02(){
    //创建验证对象
    //参数1:签名使用的算法 参数2:签名的密钥
    JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("123")).build();
    //
    DecodedJWT verify =jwtVerifier.verify("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3MDM5NDcyODMsInVzZXJuYW1lIjoi5p2O5ZubIn0.3onRy8p0G9ojnpA9u5h5ytd8hLZpGMZUyj49LTge5ao");
    System.out.println(verify.getClaim("username"));
}

Springboot整合JWT

JWT工具类

public class JWTUtil {
    private static final   String TOKENKey="qgs12345";

    /**
     * 生成token
     * @param map
     * @return 返回token
     */
    public static String getToken(Map<String,String> map){
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.DATE,7);//7天过期

        //添加payload
        JWTCreator.Builder builder = JWT.create();
        map.forEach((k,v)->{
            builder.withClaim(k,v);
        });

        builder.withExpiresAt(instance.getTime());//设置令牌过期时间
        //生成并返回token
       return builder.sign(Algorithm.HMAC256(TOKENKey)).toString();
    }

    /**
     * 验证token
     * @param token
     */
    public static void verify(String token){
        JWT.require(Algorithm.HMAC256(TOKENKey)).build().verify(token);
    }

    /**
     * 获取token中payload
     * @param token
     * @return
     */
    public static DecodedJWT getTokenInfo(String token){
        return JWT.require(Algorithm.HMAC256(TOKENKey)).build().verify(token);
    }
}

UserController

@RestController
@RequestMapping("/users")
@CrossOrigin //表示都允许跨域访问
public class UserController extends BaseController{
    @Autowired
    private UserService userModuleService;
    @RequestMapping("/login")
    public Map<String,Object> login(String username, String password){

        Map<String,Object> map =new HashMap<>();
        try {
            User data = userModuleService.login(username, password);
            Map<String,String> payload =new HashMap<>();
            payload.put("username",data.getUsername());
            //生成JWT令牌
            String token =JWTUtil.getToken(payload);
            map.put("state",true);
            map.put("msg","登入成功");
            map.put("token",token);
        }catch (Exception e){
            map.put("state",false);
            map.put("msg","登入失败");
        }
     
        return map;
    }

    //验证token
    @RequestMapping("/loginVerify")
    public Map<String,Object> loginVerify(String token){

        System.out.println(token);
        Map<String,Object> map =new HashMap<>();
        try {
            //生成JWT令牌
            JWTUtil.verify(token);
            map.put("state",true);
            map.put("msg","验证成功");
        }catch (Exception e){
            map.put("state",true);
            map.put("msg","验证失败");
        }
  
        return map;
    }

}

登录,产生token

验证token

Session认证

session用户认证流程

1、用户向服务器发送用户名和密码。

2、服务器验证通过后,在当前对话( session)里面保存相关数据,比如用户角色登录时间等。

3、服务器向用户返回一个 session_id,写入用户的 Cookie。

4、用户随后的每一次请求,都会通过Cookie,将 session_id传回服务器。

5、服务器收到 session_id,找到前期保存的数据,由此得知用户的身份。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【多省市译协盖章】2023年第九届中西部外语翻译大赛

“由中西部翻译协会共同体指导发起&#xff0c;各省市译协共建学术指导委员会&#xff0c;2023年第九届中西部外语翻译大赛由中西部翻译协会共同体秘书处&#xff08;武汉公仪网络科技有限公司&#xff09;承办。” &#xff08;证书样图&#xff09; 证书盖章单位&#xff1…

文件重命名:特殊符号影响你找文件吗?来看看这个解决方法

在日常生活和工作中&#xff0c;电脑已经成为必不可少的工具&#xff0c;而文件管理也是一项重要的任务。有时候遇到文件重命名的问题&#xff0c;例如当文件名中包含特殊符号时&#xff0c;这可能会给工作带来很大的困扰。当尝试寻找一个文件时&#xff0c;却发现因为文件名中…

Linux的账号及权限管理

一.管理用户账号 1.1 用户账户的分类 1.1.1 用户账号的分类 超级用户&#xff1a;&#xff08;拥有至高无上的权利&#xff09; root用户是Linux操作系统中默认的超级用户账号&#xff0c;对本主机拥有最高的权限&#xff0c;系统中超级用户是唯一的。普通用户&#xff1a; …

c++学习笔记(6)-类型转换

1、概念 C类型转换是将一种数据类型转换为另一种数据类型的过程。 2、分类 C中的类型转换可以从3个角度来划分&#xff1a; 根据类型转换是由程序员显式指定&#xff0c;还是由编译器自动完成&#xff0c;分为显式类型转换和隐式类型转换&#xff1b;根据参与类型转换的变量…

智能优化算法应用:基于减法平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于减法平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于减法平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.减法平均算法4.实验参数设定5.算法结果6.…

测试用例要如何写

​ &#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试…

IDEA基本设置

本博客适用于纯新手小白&#xff0c;或者刚下载IDEA想要优化开发添加配置的读者。 基础设置 不区分大小写代码补全 打开 IntelliJ IDEA。转到 “File”&#xff08;文件&#xff09; > “Settings”&#xff08;设置&#xff09;&#xff08;Windows/Linux&#xff09;或 “…

swagger1.2 apiPost工具测试接口没有问题,换成swagger 接口调测时报错 Required request body is missing

把 请求方法由get换成post GetMapping换成 PostMapping 原因apiPost自动把请求json参数封装到请求体里了&#xff0c; 但swagger没有封装&#xff0c;通过networker可以看到载荷里并没有任何东西

(C++)DS哈希查找—二次探测再散列(附思路和详细注释)

Description 定义哈希函数为H(key) key%11。输入表长&#xff08;大于、等于11&#xff09;&#xff0c;输入关键字集合&#xff0c;用二次探测再散列构建哈希表&#xff0c;并查找给定关键字。 Input 测试数据组数 1≤&#xfffd;≤50. 每组测试数据格式如下&#xff1a…

面试题:Zabbix 和 Prometheus 到底怎么选?

文章目录 前言历史简介PrometheusZabbix 架构对比PrometheusZabbix 综合对比总结 前言 新公司要上监控&#xff0c;面试提到了 Prometheus 是公司需要的监控解决方案&#xff0c;我当然是选择跟风了。 之前主要做的是 Zabbix&#xff0c;既然公司需要 Prometheus&#xff0c;…

【如何破坏单例模式(详解)】

✅如何破坏单例模式 &#x1f4a1;典型解析✅拓展知识仓✅反射破坏单例✅反序列化破坏单例✅ObjectlnputStream ✅总结✅如何避免单例被破坏✅ 避免反射破坏单例✅ 避免反序列化破坏单例 &#x1f4a1;典型解析 单例模式主要是通过把一个类的构造方法私有化&#xff0c;来避免重…

鸿蒙系统的分布式技术:重塑智能终端的未来

华为鸿蒙系统自发布以来&#xff0c;凭借其创新的分布式技术&#xff0c;改变了我们对智能终端的认知和使用方式。鸿蒙系统的分布式技术是一种全新的设计理念&#xff0c;它将不同设备、不同应用场景视为一个整体&#xff0c;通过共享、协同和无缝连接&#xff0c;为用户带来前…

android setText不生效问题

1.直接说解决方案&#xff1a; 在代码没问题的情况下&#xff0c;将你的TextView的Id改一下&#xff0c;然后再重启编译器即可(注意&#xff0c;不修改TextView的ID&#xff0c;单独重启是没有作用的&#xff01;) 2.出现问题的过程&#xff1a; 产品新增一个需求&#xff0c…

SpringBoot整合JWT+Spring Security+Redis实现登录拦截(一)登录认证

一、JWT简介 JWT 全称 JSON Web Token&#xff0c;JWT 主要用于用户登录鉴权&#xff0c;当用户登录之后&#xff0c;返回给前端一个Token&#xff0c;之后用户利用Token进行信息交互。 除了JWT认证之外&#xff0c;比较传统的还有Session认证&#xff0c;如何选择可以查看之前…

MAGVIT: Masked Generative Video Transformer

Paper name MAGVIT: Masked Generative Video Transformer Paper Reading Note Paper URL: https://arxiv.org/abs/2212.05199 Project URL: https://magvit.cs.cmu.edu/ Code URL: https://github.com/google-research/magvit TL;DR 2023 年 CMU、google 等发表 CVPR20…

[Python工程化之路] 搭建Python开发环境 包管理环境以及Linter

个人博客:Sekyoro的博客小屋 个人网站:Proanimer的个人网站 在工程化上,Python相比于Java,C#这类语言还是差了不少,不过整个生态还是不错的. 项目结构 一般有两种,一种称为flat另一种为src. ├── sample │ ├── AUTHORS.rst │ ├── docs | | ├── conf.py │ │ └…

深入Apache Commons Config:管理和使用配置文件

第1章&#xff1a;引言 咱们都知道&#xff0c;在软件开发中&#xff0c;管理配置文件是一件既重要又让人头疼的事。想象一下&#xff0c;咱们的应用程序有一堆设置需要调整&#xff0c;比如数据库的连接信息、应用的端口号&#xff0c;或者是一些功能的开关。如果这些信息硬编…

java实现广度优先搜索算法

广度优先搜索算法&#xff08;BFS&#xff09;是一种用于图遍历的算法。它从图的某个节点开始&#xff0c;依次访问其所有邻接节点&#xff0c;再依次访问邻接节点的邻接节点&#xff0c;以此类推&#xff0c;直到遍历完所有节点。 BFS使用队列数据结构来实现遍历过程。具体步…

关于 Appium 各种版本的安装,都在这里

大家在初次接触 Appium 时会看到网上各种帖子讲解如何安装 Appium&#xff0c;各种 Appium 版本的安装教程满天飞&#xff0c;而很多帖子中提供的安装教程是已经过时了的&#xff0c;容易误导初学者。 这篇文章带着你一起全面了解 Appium 各种版本如何选择如何安装。 一句话概述…

Superset 二次开发之自定义Viz Plugins(Hello World v2)

环境&#xff1a; Node.js 16npm 7 or 8安装webpack 全局安装 npm install webpack -g 安装eslint superset-frontend> npm install eslint 1.Yeoman 生成器 全局安装Yo> npm i -g yo 2.进入/superset-frontend/packages/generator-superset目录 npm i && npm…