JWT生成与解析/JWT令牌前端存储
第一步:创建项目
添加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: 80servlet:context-path: /jwt
spring:thymeleaf:#前缀,也就是模板存放的路径prefix: classpath:/templates/#编码格式encoding: UTF-8check-template-location: false#关闭缓存,不然无法看到实时页面cache: false#后缀suffix: .html#设置不严格的htmlmode: HTMLservlet: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")@ResponseBodypublic 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")@ResponseBodypublic 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>
第八步:部署运行查看结果:
- 访问http://localhost/jwt/login,在打开的login.html页面中单击登录按钮:

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

相关文章:
JWT生成与解析/JWT令牌前端存储
第一步:创建项目 添加Maven依赖: <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.62</version> </dependency> <dependency><groupId>org.s…...
[交互]前端展示服务端获取的图片
可以通过以下步骤从服务端获取图片: 引入axios库:在前端代码中使用axios库来发送HTTP请求。可以通过以下方式引入axios: import axios from axios;发送请求:使用axios发送HTTP请求,获取图片文件的二进制数据。发送请求…...
LeetCode2.两数相加
一看完题,我的想法是先算出这两个链表表示的数,然后相加,然后把这个数一位一位的分配给第三个数组,这种方法应该很简单但是要遍历三次数组,于是我就想直接一遍遍历,两个链表同时往后面遍历,把这…...
Linux编译过程与交叉编译
一.GCC由来 GCC(GNU编译器套件)是一个自由开源的编程工具集,用于编译和链接C、C和其他编程语言的程序。它由理查德斯托曼(Richard Stallman)和其他自由软件基金会(Free Software Foundation)的…...
MediaPipe+OpenCV 实现实时手势识别(附Python源码)
MediaPipe官网:https://developers.google.com/mediapipe MediaPipe仓库:https://github.com/google/mediapipe 一、MediaPipe介绍 MediaPipe 是一个由 Google 开发的开源跨平台机器学习框架,用于构建视觉和感知应用程序。它提供了一系列预训…...
为什么选择C/C++内存检测工具AddressSanitizer?如何使用AddressSanitizer?
目录 1、C程序中的内存问题 2、AddressSanitizer是什么? 3、AddressSanitizer内存检测原理简述 3.1、内存映射 3.2、插桩 4、为什么选择AddressSanitizer? 4.1、Valgrind介绍 4.2、AddressSanitizer在速度和内存方面为什么明显优于Valgrind 4.3…...
获取vue当前页面url问号后面的参数
除了使用 window.location.search 或 Vue Router 的 $route.query 来获取 URL 问号后面的参数之外,您还可以使用 JavaScript 中的正则表达式来解析 URL 中的参数部分。以下是一个示例: // 获取当前页面的完整 URL const currentURL window.location.hre…...
Linux编程之线程池的设计与实现
Linux编程之线程池的设计与实现(C98) 代码 假设服务器的硬件资源“充裕”,那么提高服务器性能的一个很直接的方法就是空间换时间, 即“浪费”服务器的硬件资源,以换取其运行效率。 提升服务器性能的一个重要方法就是…...
stm32---定时器输入捕获
一、输入捕获介绍 在定时器中断实验章节中我们介绍了通用定时器具有多种功能,输入捕获就是其中一种。 STM32F1除了基本定时器TIM6和TIM7,其他定时器都具有输入捕获功能 。输入捕获可以对输入的信号的上升沿,下降沿或者双边沿进行捕获…...
打造生产级Llama大模型服务
对于任何想要尝试人工智能或本地LLM,又不想因为意外的云账单或 API 费用而感到震惊的人,我可以告诉你我自己的旅程是如何的,以及如何开始使用廉价的消费级硬件执行Llama2 推理 。 这个项目一直在以非常活跃的速度发展,这使得它非…...
Acwing 828. 模拟栈
Acwing 828. 模拟栈 题目要求思路讲解代码展示 题目要求 思路讲解 栈:先进后出 队列:先进先出 代码展示 #include <iostream>using namespace std;const int N 100010;int m; int stk[N], tt;int main() {cin >> m;while (m -- ){string o…...
初识Docker
文章目录 Docker安装Docker简介1.什么是虚拟化、容器化?2. 为什么需要虚拟化、容器化?3. 虚拟化的实现方式主机虚拟化的实现方式容器虚拟化实现 4. 虚拟机和Docker的区别 Docker安装 基于Centos7进行安装 1.确认系统版本和CPU架构,Centos7的x86_64架构…...
HTTPS Tomcat Servlet 博客系统 软件测试的概念 Linux
第 1 题(多选题) 题目名称: 以下关于http和https说法正确的是 题目内容: A .http是超文本传输协议 B .https是超文本传输安全协议 C .http是明文传输 D .https是加密传输 第 2 题(单选题) 题目名称…...
云南财经大学《乡村振兴战略下传统村落文化旅游设计》许少辉八一著作
云南财经大学《乡村振兴战略下传统村落文化旅游设计》许少辉八一著作...
shopee——排序模型AUC还能涨吗?
文章目录 CBMRMultiCBMRSample Weight Assignment多任务推荐模型 CBMR MultiCBMR Sample Weight Assignment Click-aware Structure Transfer with Sample Weight Assignment for Post-Click Conversion Rate Estimation 每个用户的top-k 邻居每个商品的top-k 邻居平滑处理并构…...
长城网络靶场第三题
关卡描述:1.oa服务器的内网ip是多少? 先进行ip统计,开始逐渐查看前面几个ip 基本上都是b/s,所以大概率是http,过滤一下ip 第一个ip好像和oa没啥关系 第二个ip一点开就是 oa,应该就是他了。 关卡描述&a…...
Java“牵手”虾皮商品列表页数据采集+虾皮商品价格数据排序,虾皮API接口申请指南
虾皮商城是一个在线电子商务平台,总部设在新加坡,隶属于Sea Limited(冬海集团,简称为Sea)。虾皮商城于2015年在新加坡成立以来,业务范围辐射新加坡、马来西亚、菲律宾、泰国、越南、巴西等10余个市场1。拥有…...
Pyspark综合案例(pyspark安装和java运行环境配置)
一、RDD对象 PySpark支持多种数据的输入,在输入完成后,都会得到一个:RDD类的对象 RDD全称为:弹性分布式数据集(Resilient Distributed Datasets) PySpark针对数据的处理,都是以RDD对象作为载…...
虚拟机突然无法访问外部网络的现象集合
现场还原 虚拟机突然无法访问外部网络 ping 8.8.8.8的时候显示网络不可达 ping 8.8.8.8ping www.baidu.com(报:未知的名称或服务或请求超时) ping www.baidu.comyum操作 也提示错误:为仓库 ‘appstream’ 下载元数据失败 : C…...
国庆中秋特辑(一)浪漫祝福方式 用循环神经网络(RNN)或长短时记忆网络(LSTM)生成祝福诗词
目录 一、使用深度学习中的循环神经网络(RNN)或长短时记忆网络(LSTM)生成诗词二、优化:使用双向 LSTM 或 GRU 单元来更好地捕捉上下文信息三、优化:使用生成对抗网络(GAN)或其他技术…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...
FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...
给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...
