网站首页 > 精选教程 正文
近年来,随着前后端分离、微服务等架构的兴起,传统的cookie+session身份验证模式已经逐渐被基于Token的身份验证模式取代。接下来介绍如何在Spring Boot项目中集成JWT实现Token验证。
一、JWT入门
1.什么是JWT
JWT (Json web token)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519)。它定义了一种紧凑的,自包含的方式,用于通信双方之间以JSON对象的形式安全传递信息。JWT使用HMAC算法或者是RSA的公私秘钥的数字签名技术,所以这些信息是可被验证和信任的。
JWT官网: https://jwt.io/
JWT(Java版)的github地址:https://github.com/jwtk/jjwt
2.JWT的结构
在使用 JWT 之前,需要先了解它的组成结构。它是由以下三段信息构成的:
- Header 头部(包含签名和/或加密算法的类型)
- Payload 载荷 (存放有效信息)
- Signature 签名/签证
将这三段信息文本用‘.’连接一起就构成完整的JWT字符串,也是就我们需要的Token。如下所示:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0aW1lU3RhbXAiOjE2MzkwNDc1NTMxNjksInVzZXJSb2xlIjoiUk9MRV9BRE1JTiIsInVzZXJJZCI6ImFkbWluIn0.UFQLvaiQ1AThx9Fa4SRqNg-b9HPJ9y1TlgQB4-F3pi0
JWT的数据结构还是比较复杂的,Header,Payload,Signature中包含了很多信息,建议大家最好是能够了解。
3.JWT的请求流程
JWT的请求流程也特别简单,首先使用账号登录获取Token,然后后面的各种请求,都带上这个Token即可。具体流程如下:
1. 客户端发起登录请求,传入账号密码;
2. 服务端使用私钥创建一个Token;
3. 服务器返回Token给客户端;
4. 客户端向服务端发送请求,在请求头中该Token;
5. 服务器验证该Token;
6. 返回结果。
二、Spring Boot 如何集成JWT
JWT提供了基于Java组件:java-jwt帮助我们在Spring Boot项目中快速集成JWT,接下来进行SpringBoot和JWT的集成。
1.引入JWT依赖
创建普通的Spring Boot项目,修改项目中的pom.xml文件,引入JWT等依赖。示例代码如下:
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.创建&验证Token
创建通用的处理类TokenUtil,负责创建和验证Token。示例代码如下:
@Component
public class TokenUtil {
@Value("${token.secretKey}")
private String secretKey;
/**
* 加密token.
*/
public String getToken(String userId, String userRole) {
//这个是放到负载payLoad 里面,魔法值可以使用常量类进行封装.
String token = JWT
.create()
.withClaim("userId" ,userId)
.withClaim("userRole", userRole)
.withClaim("timeStamp", System.currentTimeMillis())
.sign(Algorithm.HMAC256(secretKey));
return token;
}
/**
* 解析token.
* {
* "userId": "weizhong",
* "userRole": "ROLE_ADMIN",
* "timeStamp": "134143214"
* }
*/
public Map<String, String> parseToken(String token) {
HashMap<String, String> map = new HashMap<String, String>();
DecodedJWT decodedjwt = JWT.require(Algorithm.HMAC256(secretKey))
.build().verify(token);
Claim userId = decodedjwt.getClaim("userId");
Claim userRole = decodedjwt.getClaim("userRole");
Claim timeStamp = decodedjwt.getClaim("timeStamp");
map.put("userId", userId.asString());
map.put("userRole", userRole.asString());
map.put("timeStamp", timeStamp.asLong().toString());
return map;
}
}
3.创建拦截器,验证Token
创建一个拦截器AuthHandlerInterceptor,负责拦截所有Http请求,验证Token是否有效。示例代码如下:
@Slf4j
@Component
public class AuthHandlerInterceptor implements HandlerInterceptor {
@Autowired
TokenUtil tokenUtil;
@Value("${token.refreshTime}")
private Long refreshTime;
@Value("${token.expiresTime}")
private Long expiresTime;
/**
* 权限认证的拦截操作.
*/
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
log.info("=======进入拦截器========");
// 如果不是映射到方法直接通过,可以访问资源.
if (!(object instanceof HandlerMethod)) {
return true;
}
//为空就返回错误
String token = httpServletRequest.getHeader("token");
if (null == token || "".equals(token.trim())) {
return false;
}
log.info("==============token:" + token);
Map<String, String> map = tokenUtil.parseToken(token);
String userId = map.get("userId");
String userRole = map.get("userRole");
long timeOfUse = System.currentTimeMillis() - Long.parseLong(map.get("timeStamp"));
//1.判断 token 是否过期
if (timeOfUse < refreshTime) {
log.info("token验证成功");
return true;
}
//超过token刷新时间,刷新 token
else if (timeOfUse >= refreshTime && timeOfUse < expiresTime) {
httpServletResponse.setHeader("token",tokenUtil.getToken(userId,userRole));
log.info("token刷新成功");
return true;
}
//token过期就返回 token 无效.
else {
throw new TokenAuthExpiredException();
}
}
}
拦截器创建之后,需要将拦截器注册到Spring Boot中。这和其他的拦截器注册是一样的。示例代码如下:
@Configuration
public class AuthWebMvcConfigurer implements WebMvcConfigurer {
@Autowired
AuthHandlerInterceptor authHandlerInterceptor;
/**
* 给除了 /login 的接口都配置拦截器,拦截转向到 authHandlerInterceptor
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authHandlerInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/login");
}
}
4.创建控制器
创建TokenTestController控制器,处理HTTP请求。示例代码如下:
@RestController
public class TokenTestController {
@Autowired
TokenUtil tokenUtil;
@PostMapping("/login")
public String login(@RequestBody LoginUser user){
// 先验证用户的账号密码,账号密码验证通过之后,生成Token
String role = "ROLE_ADMIN";
String token = tokenUtil.getToken(user.username,role);
return token;
}
@PostMapping("/testToken")
public String testToken(HttpServletRequest request){
String token = request.getHeader("token");
tokenUtil.parseToken(token);
return "请求成功";
}
}
5.测试验证
集成JWT成功之后,接下来验证Token是否成功,启动项目。在Postman中调用相关接口,验证功能是否正常。
首先,调用http://localhost:8080/testToken,获取token
然后,调用http://localhost:8080/testToken 验证token是否有效。
最后
以上,我们就把Spring Boot集成JWT实现Token验证介绍完了。身份验证是Web开发中非常基础的功能,后面还会介绍授权及权限管理等内容。
- 上一篇: 9种 分布式ID生成方案,让你一次学个够
- 下一篇: JWT 登录认证及 token 自动续期方案解读
猜你喜欢
- 2024-12-09 java+uniapp实现微信JSSDK扫码功能
- 2024-12-09 springSecurity多用户类型认证授权及刷新token
- 2024-12-09 JWT 登录认证及 token 自动续期方案解读
- 2024-12-09 9种 分布式ID生成方案,让你一次学个够
- 2024-12-09 Spring Boot+OAuth2,如何自定义返回的 Token 信息?
- 2024-12-09 基于JWT的token验证、原理及流程
- 2024-12-09 java使用spring mvc开发微信公众号获取token
- 2024-12-09 实战SpringBoot集成JWT实现token验证
- 2024-12-09 SpringBoot 无感刷新 Token
- 2024-12-09 干货:JWT实现token认证详解
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)