SpringBoot整合JWT的入门指南
SpringBoot整合JWT的入门指南,恰卡网带你了解更多相关信息。
目录
- 1.JWT
- 2.JWT登录执行流程图
- 3.为什么使用JWT?
- 4.JWT的组成
- 5.SpringBoot整合JWT
- 测试
- 总结
1.JWT
JWT(JSON Web Token),为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。将用户信息加密到token中,服务器不保存任何用户信息,服务器通过保存的密钥验证token的正确性。
优点
1.简介:可以通过 URL POST 参数或者在 HTTP header 发送,因为数据量小,传输速度也很快;
2.自包含:负载中可以包含用户所需要的信息,避免了多次查询数据库;
3.因为 Token 是以 JSON 加密的形式保存在客户端的,所以 JWT 是跨语言的,原则上任何 web 形式都支持;
4.不需要再服务端保存会话信息,特别适用于分布式微服务;
缺点
1.无法作废已经发布的令牌;
2.不易应对数据过期;
2.JWT登录执行流程图
3.为什么使用JWT?
- 在传统的用户登录认证中,因为http是无状态的,所以都是采用session+cokokie,用户登录成功,服务端会保存一个session,并给客户端一个sessionId,客户端会把sessionId保存在cookie中,每次请求都会携带sessionId。cookie+session模式是保存在内存中,在分布式服务中会面临session共享问题,随着用户量得增加,开销就越来越大。而JWT不需要在服务端保存会话信息,特别适合分布式微服务。
- 简洁:可以用过URL,POST参数或者在HTTP Header发送,因为数据量小,传输速度也快
- JWT支持跨语言
- 自包含: 载荷中包含了所有用户所需要的信息,避免了多次查询数据库。
4.JWT的组成
JWT由三部分构成,类似于如下:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJscyIsImV4cCI6MTYyNDU5Nzc5Nn0.4kwT1elZCb_k2D7AxbuFHM35VmBK4PcmLaqHhcHEq4_wVe8GVO8ODypGSKksTs-hraBopBCm2IC9EC2rO-GHng
第一部分为头部(header),承载两部分信息
声明类型(JWT)
声明加密算法,默认为HMAC SHA256
{ "typ","JWT", "alg","HS256" }
使用Base64加密后
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9
第二部分为payload(载荷),存放有效信息的地方,这些有效信息分为三部分:
- 标准中注册的声明
- 公共的声明
- 私有的声明
其中,标准中注册的声明 (建议但不强制使用)包括如下几个部分 :
- iss: jwt签发者;
- sub: jwt所面向的用户;
- aud: 接收jwt的一方;
- exp: jwt的过期时间,这个过期时间必须要大于签发时间;
- nbf: 定义在什么时间之前,该jwt都是不可用的;
- iat: jwt的签发时间;
- jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击
公共的声明部分:
公共的声明可以添加任何信息,一般添加用户的相关信息或其他业务需要的必要信息,但不建议添加铭感信息,因为在客户端可解密。
私有的声明部分:
私有的声明是提供者和消费者共同定义的声明,不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。
第三部分为signature(签证)
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload); //密钥就是我们定义的secret,加密后得到签证 var signature = HMACSHA256(encodedString, '密钥');
5.SpringBoot整合JWT
引入依赖
<!--JWT--> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.7.0</version> </dependency> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.4.0</version> </dependency> <!--StringUtils工具包--> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <!--ConfigurationProperties出现异常--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
配置application.yml文件
server: port: 8888 spring: jwt: #过期时间 expireTime: 1800000 #加密密钥 secret: lsyyp5201314 #token返回头部 header: LOGINTOKEN
JWT工具类
package org.best.util; import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.exceptions.TokenExpiredException; import org.springframework.boot.context.properties.ConfigurationProperties; import java.util.Date; @ConfigurationProperties(prefix = "spring.jwt") public class JWTUtils { public static String header; private static String secret; private static String expireTime; /** * 生成token * @param sub 用户唯一信息 * @return token */ public static String createToken(String sub){ return JWT .create() .withSubject(sub) .withExpiresAt(new Date(System.currentTimeMillis()+Long.parseLong(expireTime))) .sign(Algorithm.HMAC512(secret)); } /** * 根据token获取用户信息 * @param token * @return 用户信息 */ public static String validateToken(String token){ return JWT .require(Algorithm.HMAC512(secret)) .build() .verify(token) .getSubject(); } /** * 检验Token是否需要刷新 * @param token * @return */ public static boolean refreshToken(String token) { Date expireDate = null; try { expireDate = JWT .require(Algorithm.HMAC512(secret)) .build() .verify(token) .getExpiresAt(); } catch (TokenExpiredException e) { return true; } return (expireDate.getTime()-System.currentTimeMillis())<0; } public void setHeader(String header) { this.header = header; } public String getSecret() { return secret; } public void setSecret(String secret) { this.secret = secret; } public String getExpireTime() { return expireTime; } public void setExpireTime(String expireTime) { this.expireTime = expireTime; } }
自定义拦截器
package org.best.config; import org.apache.commons.lang.StringUtils; import org.best.common.TokenIsNullException; import org.best.common.TokenValidateException; import org.best.util.JWTUtils; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String logintoken = request.getHeader("LOGINTOKEN"); //如果token为空 if (StringUtils.isBlank(logintoken)){ throw new TokenIsNullException("请登录"); } //校验Token String sub = JWTUtils.validateToken(logintoken); if (StringUtils.isBlank(sub)){ throw new TokenValidateException("token校验失败"); } //更新token有效期(生产新token) if (JWTUtils.refreshToken(logintoken)){ String token = JWTUtils.createToken(sub); response.setHeader(JWTUtils.header,token); } return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
注册拦截器
package org.best.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class MyWebMvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry .addInterceptor(new LoginInterceptor()) .addPathPatterns("/find") .excludePathPatterns("/login"); } }
自定义异常
package org.best.common; /** * Token校验异常 */ public class TokenValidateException extends RuntimeException { public TokenValidateException() { } public TokenValidateException(String message) { super(message); } }
package org.best.common; /** * Token为空异常 */ public class TokenIsNullException extends RuntimeException{ public TokenIsNullException() { } public TokenIsNullException(String message) { super(message); } }
自定义Controller
package org.best.controller; import org.best.pojo.User; import org.best.util.JWTUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletResponse; @RestController public class LoginController { @GetMapping("/login") public String login(User user, HttpServletResponse response){ //这里就不做数据库查询了 //根据用户id生成token String token = JWTUtils.createToken(String.valueOf(user.getId())); //将token存入HTTP响应头中 response.setHeader(JWTUtils.header,token); return user.toString(); } @GetMapping("/find") public String find(){ return "success"; } }
测试
登录接口
我们来测试下find 接口 ,不带token会出现啥情况
带上token
总结
到此这篇关于SpringBoot整合JWT的文章就介绍到这了,更多相关SpringBoot整合JWT内容请搜索趣讯吧以前的文章或继续浏览下面的相关文章希望大家以后多多支持趣讯吧!
推荐阅读
-
洗衣机不脱水了是怎么回事(洗衣机不甩干的处理方法)
洗衣机作为大家日常生活必备的家用电器,其利用率频繁,难免会因为机械磨损、缺乏润滑油、机件老化、弹簧疲劳变形等原因,出现各种不正...
-
电子表格零基础自学教程(小白也能学明白)
可能很多人(包括我)觉得Excel不就是做个表吗,没什么好学的。然而很多大型企业在面试的时候还是会问,“会Excel吗?”“会...
-
笔记本电脑报价大全(联想笔记本多少钱)
(注意:建议在旗舰店、官方旗舰店、官网购买) 一、游戏本设计本、办公本推荐如下: 华为品牌:(全球第一大电信设备商) 1...
-
煲机软件哪个好(让耳机有个思想准备)
《无间道》中陈永仁与刘建明有过一句经典对白&mdash;&mdash;“高音甜、中音准、低音沉,总之一个词通透”。这一句话也一...
-
viewsonic平板电脑(viewsonic平板电脑刷机)
ViewSonic是一个视讯品牌,中文名字:优派。 ViewSonic 一、读音:英[vju:][?s?n?k],美[vj...
-
采访麦克风户外哪款好(讯飞智能无线麦克风C1采访神器)
对于视频创作者、直播工作者、远程培训老师、记者等媒体工作者来说,工作过程中,最让人费心的莫过于如何确保收音纯正、字幕快速生成、...
-
电脑硬件配置怎么查(详述两招快速查看电脑配置参数信息)
大家好,今天跟大家分享两个快速查看电脑配置参数信息的办法。 操作步骤如下: 1右击电脑屏幕最下方任务栏左侧的电脑徽标按钮,...
-
数据线没坏但充不上电怎么办(数据线充不上电处理方法)
苹果充电器突然充不上电是比较尴尬的问题,首先看自己的充电器数据线是不是原装,如果非原装在第一次充电时,苹果手机会提示你是否要适...
-
电脑开机出现黑屏如何处理(电脑不能开机黑屏解决方法)
电脑不能开机或者开机以后黑屏怎么解决?这里收集了所有常见的维修方法,看完秒变维修高手,实在是一篇不能错过的电脑维修教程。简单易...
-
手机宝典怎么搞(小米手机性能优化宝典)
别再总是抱怨手机卡顿,系统臃肿,反应慢,现在看完这篇文章,你会发现你并不了解小米手机,当然,文中许多方法并不是仅仅适用于小米手...