SpringBoot(二十三)SpringBoot集成JWT

news2024/11/16 19:07:46

最近整理完docker之后,突然想到,我是不是可以使用docker部署多个blog实例,来实现一下负载均衡呢?

现阶段,blog项目使用的是SESSION来做用户登录信息存储,如果配置负载均衡的话,那session其实就不是很适用了。没有办法跨实例共享。

那么该怎么办呢?很简单,使用JWT,那么何为JWT呢?

JWT(JSON WEB TOKEN)是一种开放标准 (RFC 7519),它定义了一种紧凑且独立的方式,用于在各方之间以 JSON 对象的形式安全地传输信息。此信息可以验证和信任,因为它是经过数字签名的。JWT 可以使用密钥(使用 HMAC算法)或使用 RSA 或 ECDSA 的公钥/私钥对进行签名。

上边这段话是我从百度上复制下来的。JWT简单讲就是一个加密字符串,跨语言,有过期时间。

下面我需要将现在blog中的session部分改成JWT来存储。

一:添加依赖

<!-- jwt       -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

二:添加JwtUtils.java

package com.springbootblog.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map;

public class JwtUtils
{
    //jwt秘钥 此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个
    private static final String secret_key = "camellia";
    // jwt过期时间(毫秒)
    private static final int ttl = 43200 * 1000;
    public static final String token_name = "token";

    /**
     * 生成jwt
     * 使用Hs256算法, 私匙使用固定秘钥
     * @param claims    设置的信息
     * @return
     */
    public static String createJWT(Map<String, Object> claims)
    {
        // 指定签名的时候使用的签名算法,也就是header那部分
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        Date nowDate = new Date();
        // 生成JWT的时间
        long expMillis = System.currentTimeMillis() + JwtUtils.ttl;
        Date exp = new Date(expMillis);

        // 设置jwt的body
        JwtBuilder builder = Jwts.builder()
                // 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
                .setClaims(claims)
                // 标记生成时间
                .setIssuedAt(nowDate)
                // 设置签名使用的签名算法和签名使用的秘钥
                .signWith(signatureAlgorithm, JwtUtils.secret_key.getBytes(StandardCharsets.UTF_8))
                // 设置过期时间
                .setExpiration(exp);

        return builder.compact();
    }

    /**
     * 重新生成token,根据之前的生成时间和过期时间
     * @param claims
     * @return
     */
    public static String createJWTagain(Map<String, Object> claims,Date nowDate,Date expiration)
    {
        // 指定签名的时候使用的签名算法,也就是header那部分
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        // 设置jwt的body
        JwtBuilder builder = Jwts.builder()
                // 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
                .setClaims(claims)
                // 标记生成时间
                .setIssuedAt(nowDate)
                // 设置签名使用的签名算法和签名使用的秘钥
                .signWith(signatureAlgorithm, JwtUtils.secret_key.getBytes(StandardCharsets.UTF_8))
                // 设置过期时间
                .setExpiration(expiration);

        return builder.compact();
    }

    /**
     * Token解密
     * @param token     加密后的token
     * @return
     */
    public static Claims parseJWT( String token)
    {
        // 得到DefaultJwtParser
        Claims claims = Jwts.parser()
                // 设置签名的秘钥
                .setSigningKey(JwtUtils.secret_key.getBytes(StandardCharsets.UTF_8))
                // 设置需要解析的jwt
                .parseClaimsJws(token).getBody();
        return claims;
    }

    /**
     * 验证token是否过期失效
     * @param expirationTime
     * @return
     */
    public static boolean isTokenExpired (Date expirationTime) {
        return expirationTime.before(new Date());
    }

    /**
     * 获取jwt发布时间
     * @param token     token字符串
     */
    public static Date getIssuedAtDateFromToken(String token) {
        return parseJWT(token).getIssuedAt();
    }

    /**
     * 获取jwt发布时间
     * @param token     token字符串
     */
    public static Date getExpirationDateFromToken(String token) {
        return parseJWT(token).getExpiration();
    }
}

三:后端测试TOKEN生成及解析

@GetMapping("index/login")
    public Map<String, Object> login (@RequestParam("userName") String userName, @RequestParam("passWord") String passWord){
        // 声明返回map
        Map<String, Object> result = new HashMap<>() ;
        // 声明加密参数map
        Map<String, Object> claims = new HashMap<>();
        claims.put("id",1);
        claims.put("username","camellia");
        claims.put("url","https://guanchao.site");
        claims.put("age",25);
        String token= JwtUtils.createJWT(claims);
        //System.out.println("生成的jwt:"+token);

        Claims paramList = JwtUtils.parseJWT(token);
        System.out.println("解析后的token:"+paramList);
        System.out.println("解析后的token的id"+paramList.get("id"));
        System.out.println("解析后的token的有效期"+paramList.getExpiration());
        System.out.println("解析后的token的url"+paramList.get("url"));
        result.put("code", 200);
        result.put("token", token);
        return result ;
    }

理论上来说,到这里,后端的jwt集成就成功了。

四:前端VUE集成JWT

我的逻辑是,在登录成功接口中获取后端生成的TOKEN。将其存储到浏览器的缓存localstroage中。

每次请求的时候将TOKEN值从localstroage中取出,放入axios请求的header中。这部分放在axios封装中。

具体代码如何操作,请自行百度,我这里不做展示。

五:前端集成JWT后,后端测试JWT

public Map<String, Object> getFooterData(HttpServletRequest request)
{
    // 获取token
    String token = request.getHeader(JwtUtils.token_name);
    Object userid = "";
    Object figureurl = "";
    Object nickname = "";
    Object email = "";
    if(token.equals("") || token.equals("undefined") || token.equals("null") || token.equals(null))
    {}
    else
    {
        // 解析token
        Claims paramList = JwtUtils.parseJWT(token);
        userid = paramList.get("id");
        figureurl = paramList.get("figureurl");
        nickname = paramList.get("nickname");
        email = paramList.get("email");
    }

    Map<String,Object> result = new HashMap<>(12);
    // result.put("token",token);
    result.put("code",1);
    result.put("msg","操作成功!");
    result.put("visit",visit);
    result.put("friendLinklist",friendLinklist);
    result.put("article",article);
    result.put("user",user);
    result.put("message",message);
    result.put("userid",userid);
    result.put("figureurl",figureurl == null ? "" : figureurl);
    result.put("nickname",nickname);
    result.put("email",email);
    result.put("days",days);
    return result;
}

主要的部分都有注释,参照即可。

六:一些小问题

我的项目使用的是openjdk11,openjdk11集成JWT的时候发现一个小报错:

javax/xml/bind/DatatypeConverter

解决方式很简单,添加几个依赖就可以了:

<!-- jaxb依赖包 -->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>2.4.0-b180830.0438</version>
</dependency>

以上大概就是Springboot集成JWT的过程。

有好的建议,请在下方输入你的评论。

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

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

相关文章

【苍穹外卖】学习日志-day1

目录 nginx 反向代理介绍 nginx 的优势 提高访问速度 负载均衡 保证后端服务安全 高并发静态资源 Swagger 生成 API 文档 Swagger 的使用方式 导入knife4j的maven坐标 在配置类中加入knife4j相关配置 设置静态资源映射 通过注解控制生成的接口文档 项目技术点 Token 模式 MD5 加…

炼码LintCode--数据库题库(级别:入门;数量:144道)--刷题笔记_01

目录 炼码LintCode数据库入门级别的笔记未完待续~~~ 炼码LintCode 数据库 入门级别的笔记 笔记如下&#xff0c;把所有涉及到的入门级别的知识点简单总结了一下。 以及一点点举一反三的写法。 增 INSERT INTO 表名 (列1, 列2, ...) VALUES (值1, 值2, ...);批量增 INSERT INT…

【C语言】连接陷阱探秘(1):声明与定义

目录 一、声明与定义的混淆 1.1. 声明(Declaration) 1.2. 定义(Definition) 1.3. 避免混淆的方法 1.4. 示例 二、声明与定义不匹配 2.1. 常见的不匹配情况 2.2. 解决方法 三、外部变量与静态变量的命名冲突 3.1. 外部变量命名冲突 3.2. 静态变量命名冲突 四、缺…

pycharm快速更换虚拟环境

目录 1. 选择Conda 虚拟环境2. 创建环境3. 直接选择现有虚拟环境 1. 选择Conda 虚拟环境 2. 创建环境 3. 直接选择现有虚拟环境

[代码+论文+讲解]2024数维杯A题:飞机激光测速中的频率估计问题

一、问题背景 空速是飞机相对于空气的速度&#xff0c;是飞行中需要监测的关键参数。空速与飞行状态如攻角和侧偏角密切相关。如果空速数据异常&#xff0c;很容易导致诸如失速等事故。因此&#xff0c;准确测量空速非常重要。 图1:空速激光测速的示意图 激光测速是一种可行的测…

vscode中执行git合并操作需要输入合并commit信息,打开的nano小型文本编辑器说明-

1.前提&#xff1a; VScode中的git组件执行任何合并动作的时候需要提交远程合并的commit信息&#xff0c;然后编辑器自动打开的是nano文本编辑器 2.nano编辑器说明&#xff1a; 1.保存文件&#xff1a;按 Ctrl O&#xff0c;然后按 Enter 来保存文件。 2.退出编辑器&#xf…

Docker 基础命令介绍和常见报错解决

介绍一些 docker 可能用到的基础命令&#xff0c;并解决三个常见报错&#xff1a; 权限被拒绝&#xff08;Permission Denied&#xff09;无法连接到 Docker 仓库&#xff08;Timeout Exceeded&#xff09;磁盘空间不足&#xff08;No Space Left on Device&#xff09; 命令以…

【电脑】解决DiskGenius调整分区大小时报错“文件使用的簇被标记为空闲或与其它文件有交叉”

【电脑】解决DiskGenius调整分区大小时报错“文件使用的簇被标记为空闲或与其它文件有交叉” 零、报错 在使用DiskGenius对磁盘分区进行调整时&#xff0c;DiskGenius检查出磁盘报错&#xff0c;报错信息&#xff1a;文件使用的簇被标记为空闲或与其它文件有交叉&#xff0c;…

YOLOv11 C++ TensorRT

引用 YOLOv11 C TensorRT项目是一个用C实现并使用NVIDIA TensorRT进行优化的高性能对象检测解决方案。该项目利用 YOLOv11 模型提供快速准确的对象检测&#xff0c;并利用 TensorRT 最大限度地提高推理效率和性能。 &#x1f4e2; 更新 主要特点&#xff1a; 模型转换&#x…

产品思维如何颠覆我的开发与盈利观-营销自己

之前&#xff0c;我独自一人开发了一个名为“心情追忆”的小程序&#xff0c;旨在帮助用户记录日常的心情变化及重要时刻。从项目的构思、设计、前端&#xff08;小程序&#xff09;开发、后端搭建到最终部署&#xff0c;所有环节都由我一人包办。经过一个月的努力&#xff0c;…

Spring Boot框架:电商系统的快速构建

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本网上商城系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&…

【网页设计】CSS3 进阶(动画篇)

1. CSS3 2D 转换 转换&#xff08;transform&#xff09;是CSS3中具有颠覆性的特征之一&#xff0c;可以实现元素的位移、旋转、缩放等效果 转换&#xff08;transform&#xff09;你可以简单理解为变形 移动&#xff1a;translate旋转&#xff1a;rotate缩放&#xf…

Android12的ANR解析

0. 参考&#xff1a; ANR分析 深入理解 Android ANR 触发原理以及信息收集过程 1.ANR的触发分类: ANR分为4类&#xff1a; InputDispatchTimeout&#xff1a;输入事件分发超时5s,包括按键和触摸事件。BroadcastTimeout&#xff1a;比如前台广播在10s内未执行完成&#xff0…

【eNSP】路由基础与路由来源——静态路由实验

路由是数据包从源地址到目的地址的传输路径&#xff0c;静态路由是指网络管理员手动配置的路由条目&#xff0c;用于指定数据包从源地址到目的地址的固定路径。以下是关于静态路由的详细介绍。 一、路由的基础知识点 路由的定义&#xff1a; 路由是指在计算机网络中&#xff…

【AI声音克隆整合包及教程】第二代GPT-SoVITS V2:创新与应用

一、引言 随着科技的迅猛发展&#xff0c;声音克隆技术已经成为一个炙手可热的研究领域。SoVITS&#xff08;Sound Voice Intelligent Transfer System&#xff09;&#xff0c;作为该领域的先锋&#xff0c;凭借其卓越的性能和广泛的适用性&#xff0c;正在为多个行业带来前所…

VScode-Java开发常用插件

中文——界面易读 字体主题——代码可观 头注释——项目信息明了 java开发包——java必备 git协作开发——版本控制

jmeter常用配置元件介绍总结之逻辑控制器

系列文章目录 安装jmeter jmeter常用配置元件介绍总结之逻辑控制器 逻辑控制器1.IF控制器2.事务控制器3.循环控制器4.While控制器5.ForEach控制器6.Include控制器7.Runtime控制器8.临界部分控制器9.交替控制器10.仅一次控制器11.简单控制器12.随机控制器13.随机顺序控制器14.吞…

探索 HTML 和 CSS 实现的蜡烛火焰

效果演示 这段代码是一个模拟蜡烛火焰的HTML和CSS代码。它创建了一个具有动态效果的蜡烛火焰动画&#xff0c;包括火焰的摆动、伸缩和光晕的闪烁。 HTML <div class"holder"><div class"candle"><div class"blinking-glow"&g…

机器学习 - 为 Jupyter Notebook 安装新的 Kernel

https://ipython.readthedocs.io/en/latest/install/kernel_install.html 当使用jupyter-notebook --no-browser 启动一个 notebook 时&#xff0c;默认使用了该 jupyter module 所在的 Python 环境作为 kernel&#xff0c;比如 C:\devel\Python\Python311。 如果&#xff0c…

SwiftUI-基础入门

开发OS X 图形应用界面时有三种实现方式&#xff1a;XIB、Storyboard、SwiftUI。Storyboard基于XIB做了优化&#xff0c;但XIB基本被放弃了&#xff0c;而SwiftUI是苹果公司后来开发的一套编程语言&#xff0c;用来平替Objective-C。虽然现在Swift 6 还是有些不完善的地方&…