SpringBoot2.0高级案例(10):整合 JWT 框架,解决Token跨域验证问题

article/2025/6/19 10:22:42
GitHub源码地址:知了一笑
https://github.com/cicadasmile/middle-ware-parent

一、传统Session认证

1、认证过程

1、用户向服务器发送用户名和密码。
2、服务器验证后在当前对话(session)保存相关数据。
3、服务器向返回sessionId,写入客户端 Cookie。
4、客户端每次请求,需要通过 Cookie,将 sessionId 回传服务器。
5、服务器收到 sessionId,验证客户端。

2、存在问题

1、session保存在服务端,客户端访问高并发时,服务端压力大。
2、扩展性差,服务器集群,就需要 session 数据共享。

二、JWT简介

JWT(全称:JSON Web Token),在基于HTTP通信过程中,进行身份认证。

1、认证流程

1、客户端通过用户名和密码登录服务器;
2、服务端对客户端身份进行验证;
3、服务器认证以后,生成一个 JSON 对象,发回客户端;
4、客户端与服务端通信的时候,都要发回这个 JSON 对象;
5、服务端解析该JSON对象,获取用户身份;
6、服务端可以不必存储该JSON(Token)对象,身份信息都可以解析出来。

2、JWT结构说明

抓一只鲜活的Token过来。

{"msg": "验证成功","code": 200,"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImlhdCI6iZEIj3fQ.uEJSJagJf1j7A55Wwr1bGsB5YQoAyz5rbFtF"
}

上面的Token被手动格式化了,实际上是用"."分隔的一个完整的长字符串。

JWT结构

1、头部(header) 声明类型以及加密算法;
2、负载(payload) 携带一些用户身份信息;
3、签名(signature) 签名信息。

3、JWT使用方式

通常推荐的做法是客户端在 HTTP 请求的头信息Authorization字段里面。

Authorization: Bearer <token>

服务端获取JWT方式

String token = request.getHeader("token");

三、与SpringBoot2整合

1、核心依赖文件

<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.7.0</version>
</dependency>

2、配置文件

server:port: 7009
spring:application:name: ware-jwt-token
config:jwt:# 加密密钥secret: iwqjhda8232bjgh432[cicada-smile]# token有效时长expire: 3600# header 名称header: token

3、JWT配置代码块

@ConfigurationProperties(prefix = "config.jwt")
@Component
public class JwtConfig {/** 根据身份ID标识,生成Token*/public String getToken (String identityId){Date nowDate = new Date();//过期时间Date expireDate = new Date(nowDate.getTime() + expire * 1000);return Jwts.builder().setHeaderParam("typ", "JWT").setSubject(identityId).setIssuedAt(nowDate).setExpiration(expireDate).signWith(SignatureAlgorithm.HS512, secret).compact();}/** 获取 Token 中注册信息*/public Claims getTokenClaim (String token) {try {return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();}catch (Exception e){e.printStackTrace();return null;}}/** Token 是否过期验证*/public boolean isTokenExpired (Date expirationTime) {return expirationTime.before(new Date());}private String secret;private long expire;private String header;// 省略 GET 和 SET
}

四、Token拦截案例

1、配置Token拦截器

@Component
public class TokenInterceptor extends HandlerInterceptorAdapter {@Resourceprivate JwtConfig jwtConfig ;@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception {// 地址过滤String uri = request.getRequestURI() ;if (uri.contains("/login")){return true ;}// Token 验证String token = request.getHeader(jwtConfig.getHeader());if(StringUtils.isEmpty(token)){token = request.getParameter(jwtConfig.getHeader());}if(StringUtils.isEmpty(token)){throw new Exception(jwtConfig.getHeader()+ "不能为空");}Claims claims = jwtConfig.getTokenClaim(token);if(claims == null || jwtConfig.isTokenExpired(claims.getExpiration())){throw new Exception(jwtConfig.getHeader() + "失效,请重新登录");}//设置 identityId 用户身份IDrequest.setAttribute("identityId", claims.getSubject());return true;}
}

2、拦截器注册

@Configuration
public class WebConfig implements WebMvcConfigurer {@Resourceprivate TokenInterceptor tokenInterceptor ;public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(tokenInterceptor).addPathPatterns("/**");}
}

3、测试接口代码

@RestController
public class TokenController {@Resourceprivate JwtConfig jwtConfig ;// 拦截器直接放行,返回Token@PostMapping("/login")public Map<String,String> login (@RequestParam("userName") String userName,@RequestParam("passWord") String passWord){Map<String,String> result = new HashMap<>() ;// 省略数据源校验String token = jwtConfig.getToken(userName+passWord) ;if (!StringUtils.isEmpty(token)) {result.put("token",token) ;}result.put("userName",userName) ;return result ;}// 需要 Token 验证的接口@PostMapping("/info")public String info (){return "info" ;}
}

五、源代码地址

GitHub地址:知了一笑
https://github.com/cicadasmile/middle-ware-parent
码云地址:知了一笑
https://gitee.com/cicadasmile/middle-ware-parent

转载于:https://my.oschina.net/cicadasmile/blog/3078658


http://chatgpt.dhexx.cn/article/EDL5Uk7U.shtml

相关文章

SpringBoot集成JWT实现token验证以及代码演示

一、JWT的主要应用场景 身份认证在这种场景下&#xff0c;一旦用户完成了登陆&#xff0c;在接下来的每个请求中包含JWT&#xff0c;可以用来验证用户身份以及对路由&#xff0c;服务和资源的访问权限进行验证。由于它的开销非常小&#xff0c;可以轻松的在不同域名的系统中传…

2018.8.2课堂笔记

一.用户配置文件与密码配置文件 1.1 /etc/passwd是由 “ &#xff1a;” 分割7个字段&#xff0c;每个字段的含义如下&#xff1a; [rootlocalhost ~]# cat /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/no…

python爬虫反虫之setcookie

作者原文传送littleywww.littley.top 反爬表现 在使用python或rust进行爬虫的时候的有时会遇到请求返回一段含有只含有js代码的html页面如图&#xff1a; 分析及优化文件 首先解决转义字符\x63\x73\x4b&#xff0c;转义字符可以通过console.log()打印出来&#xff0c;最方…

java 数据抓取 动态获得cookies里变动的属性_Java爬取CSDN博客遇到setCookie问题

最近有一个需求就是爬取CSDN上的数据&#xff0c;但是目前遇到了一个问题就是关于获取CSDN的cookie的问题。到目前为止并没有什么好的办法。希望大家可以给我留言&#xff0c;我们一起探讨。。 在我没有设置cookie的时候&#xff0c;会报以下错误。 function setCookie(name,va…

js的cookie操作

cookie.js: //这个cookie的js代码借用的老外的&#xff0c;我加了中文注释--原文:http: //www.echoecho.com/jscookies02.htm ///设置cookie function setCookie(NameOfCookie, value, expiredays) { //参数:三个变量用来设置新的cookie: //cookie的名称,存储的Cookie值, …

蓝牙 宽带通话 (wide band speech)WBS 剖析(一) -- profile层

一.概述 WBS&#xff08;wide band speech&#xff09;通俗来讲就是蓝牙宽带通话&#xff0c;通话数据frequency 16K&#xff0c;采用msbc编解码&#xff08;chip中实现&#xff09; 和NBS&#xff08;narrow band speech&#xff09;相对&#xff0c;NBS通俗来讲是窄带通话&a…

通话参数配置的经验和技巧

整体的通话信号流程如下&#xff1a; MIC采集信号 -> 放大器 -> ADC采集 -> 通话MIC数字增益 -> AEC算法 -> ANS降噪算法 -> 通话MIC后端数字增益 -> 通话EQ -> 蓝牙上行。 配置中如图所示&#xff1a; MIC去直流fliter配置&#xff1a;MIC高通flite…

CHOLAN:一种模块化实体链接方法

CHOLAN: A Modular Approach for Neural Entity Linking on Wikipedia and Wikidata 论文链接&#xff1a;https://arxiv.org/abs/2101.09969 (EACL 2021) 代码实现&#xff1a;https://github.com/ManojPrabhakar/CHOLAN ABSTRACT 本文作者提出了实现在知识库上进行端到端…

高清语音技术(WBS)及其在手机和蓝牙耳机中的实现

高清语音也被称为宽带语音&#xff0c;是一种能为蜂窝网络、移动电话和无线耳机传输高清、自然语音质量的音频技术。与传统的窄带电话相比&#xff0c;高清语音很大程度上提高了语音质量&#xff0c;减少了听觉负担。 通信产业链上的所有网络和设备都需支持高清语音才能体现出该…

蓝牙编码格式Codec的优先级配置

【Bluetooth】Android版本所支持的蓝牙协议code查询 Android版本所支持的蓝牙协议code查询方法&#xff1a; 协议配置文件有2个&#xff0c;一个是谷歌源生的&#xff0c;一个是高通自己添加的。 优先级&#xff1a;高通 > 谷歌。对于同一种协议会进行覆盖。 其中&#xff…

基于Android Q的蓝牙通话无声问题

分享一下这几天改蓝牙通话无声的bug&#xff0c;文章有点长&#xff0c;希望各位看官看完能帮助到大家—今天分析的主题是蓝牙通话没有声音之运行流程分析 一. 结果说在前面 ​ 蓝牙通话分别有七个阶段&#xff0c;基本上每个阶段都会走到底层&#xff0c;把数据回调到上层&a…

BQB pts测试

测试BQB的pts dongle是在蓝牙SIG官网买的,链接是 https://store.bluetooth.com/12210888/orders/d3b63cfd9d3d5a22c2e08ad9711a91c4 pts dongle最新的测试结果 ACS-BV-07-I/ACS-BV-12-I/ACS-BI-13-I 这三个是接完电话就fail ICA-BV-02-I/TCA-BV-01-I 这两个是挂不了电话 ICR-B…

蓝牙btsnoop log,HFP协议连接流程详解,以及RFCOMM连接和常用AT指令

HFP&#xff08;Hands-Free&#xff09;&#xff1a;蓝牙免提协议,两个角色AG&#xff0c;HF端&#xff0c;AG端通常是手机设备&#xff0c;HF免提端一般为耳机车载等&#xff0c;hfp的连接首先要进行SDP&#xff0c;然后建立RFCOMM&#xff0c;然后SLC连接完成&#xff0c;HFP…

蓝牙协议HFP(Hands-Free Profile)电话免提协议 Connection management 连接管理HFP SLC 的建立跟释放

零. 概述 本文章主要讲下电话免提协议HFP&#xff08;Hands-Free Profile&#xff09;Connection management。包括connection establishment 跟connection realease&#xff0c;那connection establishment又会涉及到HFP SLC的建立过程。 本节讲解的内容就是一下HFP fea…

蓝牙A2DP和HFP编解码

一、A2DP A2DP全名是&#xff08;Advanced Audio Distribution Profile&#xff09; 蓝牙音频传输模型协定&#xff0c;提供通过蓝牙连接传输音频流的能力&#xff0c;比如手机播放音乐&#xff0c;蓝牙耳机通过蓝牙连接听歌。 mp3和flac音频编码都是在PCM音频编码基础上二次编…