JWT
Posted SmallCuteMonkey
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JWT相关的知识,希望对你有一定的参考价值。
六、JWT(json Web Token)一个别人封装好的工具类生成相关的token
- 用自定义的token生成的时效性不可以进行定义
- 安全性较差
6.1生成JWT
-
添加依赖:
<!-- jwt生成 --> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.10.3</version> </dependency> <!-- jjwt生成--> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency>
UserServiceimpl生成token:
HashMap<String,Object> map=new HashMap<>();
JwtBuilder builder= Jwts.builder();
String token = builder.setSubject(username) //主题就是token中携带的数据
.setIssuedAt(new Date()) //设置token的生成时间
.setId(users.get(0).getUserId() + "") //设置用户的id为tokenid
.setClaims(map) //map中可以存放用户的角色权限信息
.setExpiration(new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000)) //设置token的过期时间
.signWith(SignatureAlgorithm.HS256, "houzhicong") //设置加密的方式
.compact();
// 验证成功
ShopController进行解析Token:
package com.qfedu.fmmall.controller;
import com.qfedu.fmmall.utils.Base64Utils;
import com.qfedu.fmmall.vo.ResultStatus;
import com.qfedu.fmmall.vo.ResultVO;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@CrossOrigin
@Api(value = "提供购物车业务相关的接口",tags = "购物车管理接口")
@RequestMapping("/shopcart")
public class ShopCartController {
@RequestMapping("/list")
@ApiImplicitParam(dataType = "string",name = "token",value = "登录的一个标志",required = true)
public ResultVO shopcartList(String token){
// 校验输入的token看看是否是用户自己登录的token
// String decode = Base64Utils.decode(token);
if(token==null){
return new ResultVO(ResultStatus.NO, "请先登录", null);
}else {
JwtParser parser= Jwts.parser();
parser.setSigningKey("houzhicong");//解析token 必须和生成token时候生成的密码一致
// 如果token正确(密码正确,有效期内) 则正常执行,否则抛出异常
try{
Jws<Claims> claimsJws=parser.parseClaimsJws(token);
Claims body=claimsJws.getBody();//获取token中的用户数据
String subject=body.getSubject();//获取生成token设置subject
String v1=body.get("key1",String.class);//获取生成token时存储的Claims的map中的值
return new ResultVO(ResultStatus.OK, "success", null);
}catch (Exception e){
return new ResultVO(ResultStatus.NO, "登录已经过期,请重新登录!!", null);
}
}
}
}
6.2使用拦截器进行拦截
- 创建一个CheckTokenInterceptor
- 创建一个拦截器的类
6.3.1有
package com.qfedu.fmmall.config;
import com.qfedu.fmmall.interceptor.CheckTokenInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
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 InterceptorConfig implements WebMvcConfigurer {
@Autowired
private CheckTokenInterceptor checkTokenInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CheckTokenInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/user/**"
,"/doc.html"
,"/swagger-ui/**");
}
}
6.3使用请求头进行传递token
前端但凡访问受限资源,都必须携带token请求,token可以通过请求行(params),请求头(header),以及请求体(data)传递,但习惯使用header传递
axios通过请求头传值 里面的参数用Headers 不用Params
axios({
method:"get",
url:baseUrl+"shopcart/list",
Headers:{
token:this.token,
}
}).then(function (res) {
console.log(res);
});
},
6.3.1前端会发送预险性请求,需要拦截器进行放行
package com.qfedu.fmmall.interceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qfedu.fmmall.vo.ResultStatus;
import com.qfedu.fmmall.vo.ResultVO;
import io.jsonwebtoken.*;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@Configuration
public class CheckTokenInterceptor implements HandlerInterceptor {
// 打ov 可以看到它的方法
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getParameter("token");
// System.out.println("token----------");
// 前端会发送预险性请求
String method = request.getMethod();
if("options".equalsIgnoreCase(method)){
return true;
}
if(token==null){
// 提示用户进行登录
PrintWriter out = response.getWriter();
ResultVO resultVO= new ResultVO(ResultStatus.NO, "请先登录", null);
// 抽出一个方法进行
doResponse(response,resultVO);
// 拦截
return false;
}else {
// 验证token
try{
JwtParser parser= Jwts.parser();
parser.setSigningKey("houzhicong");
Jws<Claims> claimsJws=parser.parseClaimsJws(token);
return true;
}catch (ExpiredJwtException e){
ResultVO resultVO= new ResultVO(ResultStatus.NO, "登录过期,请重新登录", null);
doResponse(response,resultVO);
return false;
}
catch (UnsupportedJwtException e){
ResultVO resultVO= new ResultVO(ResultStatus.NO, "Token不合法,请自重", null);
doResponse(response,resultVO);
return false;
}
catch (Exception e){
ResultVO resultVO= new ResultVO(ResultStatus.NO, "请先登录", null);
doResponse(response,resultVO);
return false;
}
}
}
private void doResponse(HttpServletResponse response, ResultVO resultVO) throws IOException {
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
// 写上Json格式的resultVO
String s = new ObjectMapper().writeValueAsString(resultVO);
out.println(s);
out.flush();
out.close();
}
}
以上是关于JWT的主要内容,如果未能解决你的问题,请参考以下文章
OkHttpInterceptor 从 kotlin 拦截器导航到登录片段
AttributeError: ‘str‘ object has no attribute ‘decode‘解决方法
《代码实例》jwt参与用户凭证方式,生成jwt,security整合jwt
我已经在 Spring Boot 代码中实现了 JWT 令牌安全性。如何在我的代码中的任何地方获取 jwt 令牌?需要保存审核