JWT生成与解析/JWT令牌前端存储

news2024/12/27 11:15:54

第一步:创建项目

添加Maven依赖:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.62</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.2</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency>
<!--        集成Thymeleaf-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
    <groupId>net.sourceforge.nekohtml</groupId>
    <artifactId>nekohtml</artifactId>
    <version>1.9.22</version>
</dependency>

在resources/static目录下创建js文件夹,然后在其中添加jquery3.3.1.js文件

在这里插入图片描述

编辑application.yml:

server:
    port: 80
    servlet:
        context-path: /jwt
spring:
    thymeleaf:
        #前缀,也就是模板存放的路径
        prefix: classpath:/templates/
        #编码格式
        encoding: UTF-8
        check-template-location: false
        #关闭缓存,不然无法看到实时页面
        cache: false
        #后缀
        suffix: .html
        #设置不严格的html
        mode: HTML
        servlet:
            content-type: text/html

第二步:创建表示用户的实体类:

@Getter
@Setter
@ToString
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
    private static final long serialVersionUID = -8390887042859558153L;
    private Integer id;
    private String username;
    private String password;
}

第三步:创建常量类:

public interface JwtConst {
    //JWT签发者
    String JWT_ID = "098f6bcd4621d373cade4e832627b4f6";
    // 密钥, 经过Base64加密, 可自行替换
    String JWT_SECRECT = "MDk4ZjZiY2Q0NjIxZD";
    // 过期时间,单位毫秒
    int JWT_TTL = 60*60*1000;
}

第四步:Jwt工具类:

public class JwtUtil {
   private static Key key =  Keys.secretKeyFor(SignatureAlgorithm.HS256);
    public static String createJWT(String id, String subject, int ttl) {
        Calendar calendar = Calendar.getInstance();
        JwtBuilder builder = Jwts.builder()
                .setId(id)  //JWT唯一标识
                .setIssuedAt(calendar.getTime()) //签发时间
                .setSubject(subject) //JWT的主题,比如JSON类型的User对象
                .signWith(key);
        calendar.add(Calendar.MINUTE, ttl); // ttl过期时间,单位分钟
        builder.setExpiration(calendar.getTime()); //过期时间
        return builder.compact();
    }
    public static Claims parseJwt(String jwt){
        Claims claims = Jwts.parserBuilder().setSigningKey(key)
.build().parseClaimsJws(jwt).getBody();
        return claims;
    }
    public static String createSubject(User user){
        return JSON.toJSONString(user);
    }
}

第五步:创建表示服务器端返回结果的类:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result<T> {
    private int code;
    private String msg;
    private T data;
    public Result(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }
}

第六步:创建Controller:

生成、解析JWT的Controller

@Controller
@RequestMapping("/jwt")
public class JWTController {
    @RequestMapping("/login")
    @ResponseBody
    public Result<String> login(String username, String password) {
        if (username == null || password == null) {
            return new Result<String>(789, "用户名或密码不正确", null);
        }
        User user = new User(1001, username, password);
        String jwt = JwtUtil.createJWT(JwtConst.JWT_ID, 
JwtUtil.createSubject(user), JwtConst.JWT_TTL);
        System.out.println(jwt);
        return new Result<>(200, "请求成功!", jwt);
    }
    @RequestMapping("/parseJwt")
    @ResponseBody
    public User parseJwt(HttpServletRequest request) {
        String jwt = request.getHeader("Authorization");
        String token = JSON.parseObject(jwt).getString("token");
        Claims claims = JwtUtil.parseJwt(token);
        String subject = claims.getSubject();
        User user = JSON.parseObject(subject, User.class);
        System.out.println(user);
        return user;
    }
}

页面分发的Controller:

@Controller
public class DispatchController {
    @GetMapping("/login")
    public String showLogin(){
        return "/login";
    }
    @GetMapping("/showJwt")
    public String showJwt(){
        return "showJwt";
    }
    @GetMapping("/index")
    public String index(){
        return "index";
    }
}

第七步:前端页面:

login.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>登录页面</title>
        <script src="js/jquery3.5.1.js" type="text/javascript"></script>
    </head>
    <body>
        <form id="loginForm">
            <input type="text" name="username" value="zhangsan"><br>
            <input type="password" name="password" value="123456">
        </form>
        <button id="btn">登录</button>
        <script>
            $(function () {
                $("#btn").click(function () {
                    $.ajax({
                        type: "POST",//请求方式
                        url: "jwt/login",  //请求地址
                        dataType: "JSON", //预期服务器端返回的数据的类型
                        data: $("#loginForm").serialize(),//数据,json字符串
                        success: function (result) { //请求成功
                            console.log(result);
                            if (result.code == 200) {
                                //获取令牌并保存到本地
                                localStorage.setItem("token", '{"token":"' + result.data + '"}');
                            }
                            if (result.code == 789) {
                                window.location = "login";
                            }
                        },
                        error: function (e) {  //请求失败,包含具体的错误信息
                            console.log(e.status);
                            console.log(e.responseText);
                        }
                    });
                });
            });
        </script>
    </body>
</html>

注:第一次点登录按钮时,无法将token数据保存在Application中,原因未找到,发现原因的朋友麻烦告诉我一声。

index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>首页</title>
        <script src="js/jquery3.3.1.js" type="text/javascript"></script>
    </head>
    <body>
        首页启动时请求后台的解析Jwt的的请求
        <div id="sh"></div>
        <script>
            $(function () {
                $.ajax({
                    url: "jwt/parseJwt",
                    headers: {Authorization: localStorage.getItem("token")},
                    success:function (res) {
                        console.info(res);
                        $("#sh").text(JSON.stringify(res));
                    }
                })
            });
        </script>
    </body>
</html>

第八步:部署运行查看结果:

  1. 访问http://localhost/jwt/login,在打开的login.html页面中单击登录按钮:
    在这里插入图片描述

注:第一次点登录按钮时,无法将token数据保存在Application中,原因未找到。
2. 访问http://localhost/jwt/index,在页面上会看到:
在这里插入图片描述

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

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

相关文章

【C++】深拷贝和浅拷贝 ② ( 默认拷贝构造函数是浅拷贝 | 代码示例 - 浅拷贝造成的问题 )

文章目录 一、默认拷贝构造函数是浅拷贝1、默认拷贝构造函数2、默认拷贝构造函数是浅拷贝机制 二、代码示例 - 浅拷贝造成的问题 一、默认拷贝构造函数是浅拷贝 1、默认拷贝构造函数 如果 C 类中 没有定义拷贝构造函数 , C 编译器会自动为该类提供一个 " 默认的拷贝构造函…

GeoJSON转STL:地形3D打印

我们通过将 GeoJSON 形状坐标提取到点云中并使用 Open3d 应用泊松重建&#xff0c;从 GeoJSON 数据重建 STL 网格。 推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景 我对打印 GeoJSON 山丘的第一次尝试深感不满&#xff0c;因此想出了一个三步流程&#xff0c;仅使用开源…

Acwing 828. 模拟栈

Acwing 828. 模拟栈 题目要求思路讲解代码展示 题目要求 思路讲解 栈&#xff1a;先进后出 队列&#xff1a;先进先出 代码展示 #include <iostream>using namespace std;const int N 100010;int m; int stk[N], tt;int main() {cin >> m;while (m -- ){string o…

【JVM】经典垃圾收集器

文章目录 说明新生代收集器Serial收集器ParNew收集器Parallel Scavenge收集器 老年代收集器Serial Old收集器Parallel Old收集器CMS收集器 Garbage First收集器需要解决的问题运作过程CMS和G1的区别 说明 Java中有许多垃圾收集器&#xff08;Garbage Collector&#xff0c;GC&…

Spring Cloud Alibaba系列之nacos:(5)源码本地环境搭建

传送门 Spring Cloud Alibaba系列之nacos&#xff1a;(1)安装 Spring Cloud Alibaba系列之nacos&#xff1a;(2)单机模式支持mysql Spring Cloud Alibaba系列之nacos&#xff1a;(3)服务注册发现 Spring Cloud Alibaba系列之nacos&#xff1a;(4)配置管理 为什么要搭建本地…

范文展示,如何三步写出一篇满意的论文

第一步&#xff1a;输入文章关键信息 文章标题&#xff0c;写论文的话即为拟定的论文标题&#xff0c;例如这篇范文中的题目为“阳明心学研究” 关键词&#xff0c;可以写出多个论文主题相关的关键词&#xff0c;用逗号分开&#xff0c;例如这篇范文中只写了一个关键词“王阳…

CentOS 7.6使用mysql-8.0.31-1.el7.x86_64.rpm-bundle.tar安装Mysql 8.0

https://downloads.mysql.com/archives/community/是社区版的官网&#xff0c;可以选择版本下载。 cat /etc/redhat-release可以看到系统版本是CentOS Linux release 7.6.1810 (Core)&#xff0c;uname -r可以看到版本是3.10.0-957.el7.x86_64。 yum remove -y mysql-libs把…

计算机硬件基本组成和各硬件工作原理

计算机硬件基本组成和各硬件工作原理 计算机硬件基本组成早期冯若依曼机的结构冯若依曼机的特点 现代计算机的结构思维导图 各硬件工作原理主存储器运算器控制器I/O 计算机硬件基本组成 计算机硬件基本组成可分两大类 1.早期冯若依曼机的结构 2.现代计算机的结构 早期冯若依曼机…

类与对象的创建

package com.mypackage.oop.later;//学生类 //类里面只存在属性和方法 public class Student {//属性&#xff1a;字段//在类里面方法外面定义一个属性&#xff08;或者说是变量&#xff09;&#xff0c;然后在方法里面对他进行不同的实例化String name; //会有一个默认值&…

在word文档中找不到endnote的选项卡

本人由于在下载endnote之后才下载的office&#xff0c;所以导致在word文档中找不到endnote的选项卡&#xff0c;自己摸索到了解决方法。 首先确保已经拥有word与endnote之后&#xff0c;右键endnote打开所在文件夹&#xff1a; 在文件夹中找到这个Configure endnote.exe运行 之…

three.js简单3D图形的使用

npm init vitelatest //创建一个vite的脚手架 选择 Vanilla 之后自己处理一下 在main.js中写入 // 导入three.js import * as THREE from three// 创建场景 const scene new THREE.Scene();// 创建相机 const camera new THREE.PerspectiveCamera(45, //视角window.inner…

【Unity程序技巧】Unity中的单例模式的运用

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

el-checkbox-group限制勾选数量

<!--* Description: 视频监控 页面* Author: mhf* Date: 2023-08-15 13:26:33 --> <template><div class"videoSurveillance"><el-row :gutter"24"><el-col :span"4"><div class"videoSurveillance-left&…

亚马逊评分规则是什么,如何提高亚马逊等级评分-站斧浏览器

亚马逊平台的账户评级问题&#xff0c;如果账号评级比较差的话&#xff0c;那么会有一些不好的影响&#xff0c;因此卖家朋友们需要想办法去提升自己的账户评级。那么亚马逊评分规则是什么&#xff0c;如何提高亚马逊等级评分。 亚马逊评分规则是什么&#xff1f; 所有新卖家…

看阿里测试工程师如何玩转postman+newman+jenkins接口自动化

postman用来做接口测试非常方便&#xff0c;接口较多时&#xff0c;则可以实现接口自动化 一、环境准备 1.安装nodejs6.0 安装nodejs6.0&#xff08;github上面写的版本要求&#xff09;&#xff0c;用于安装newman4.0&#xff0c;到nodejs官网下载即可https://nodejs.org/en/…

集成Activiti-Modeler流程设计器

集成Activiti-Modeler流程设计器 Activiti Modeler 是 Activiti 官方提供的一款在线流程设计的前端插件&#xff0c;可以方便流程设计与开发人员绘制流程图&#xff0c;保存流程模型&#xff0c;部署至流程定义等等。 1、材料准备 首先我们需要获取activiti-explorer.zip&…

(三十)大数据实战——HBase集成部署安装Phoenix

前言 Phoenix 是一个开源的分布式关系型数据库查询引擎&#xff0c;它基于 Apache HBase构建。它提供了在 Hadoop 生态系统中使用 SQL查询和事务处理的能力。本节内容我们主要介绍一下Hbase如何集成部署安装Phoenix服务工具&#xff0c;并集成hive框架&#xff0c;能够快速、灵…

什么是16S rRNA,rDNA, 菌群研究为什么用16S测序,细菌如何命名分类?

谷禾健康 当谈到肠道菌群研究时&#xff0c;16S测序是一种常用的方法&#xff0c;它在了解微生物组成和多样性方面非常重要且实用。 16S rRNA是细菌和古细菌中的一个高度保守的基因片段&#xff0c;同时具有一定的变异性。通过对16S rRNA基因进行测序&#xff0c;可以确定微生物…

9.3.5网络原理(应用层HTTP/HTTPS)

一.HTTP: 1. HTTP是超文本传输协议,除了传输字符串,还可以传输图片,字体,视频,音频. 2. 3.HTTP协议报文格式:a.首行,b.请求头(header),c.空行(相当于一个分隔符,分隔了header和body),d.正文(body). 4. 5.URL:唯一资源描述符(长度不限制). a. b.注意:查询字符串(query stri…

Linux内核源码分析 (B.x)Linux内核的页面分配机制

一、伙伴系统 如果不遵循以上原则&#xff0c;在一个很大的连续空间里&#xff0c;会出现不连续的空洞&#xff0c;造成外部碎片 一般MAX_ORDER取11&#xff0c;也就是说Linux内核最大分配的最大内存块为2^10个页面&#xff0c;大小为4MB。 二、迁移类型 使用迁移类型可以实现…