一、什么是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>
- 在config文件里添加WebConfiguration文件
说明:除了user、login 其他的都务必添加上,这些文件都是swgger的文件,如果你使用了Swgger请添加忽略拦截,反之。
package com.example.hamlet.config;
import com.example.hamlet.handler.TokenInterceptor;
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;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName WebConfiguration
* @Description TODO
* @Author Hamlet
* @Date 2022/11/9 16:51
* @Version 1.0
*/
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Autowired
private TokenInterceptor tokenInterceptor;
/**
* 配置拦截器、拦截路径
* 每次请求到拦截的路径,就会去执行拦截器中的方法
* @param
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
List<String> excludePath = new ArrayList<>();
//排除拦截,除了登录,其他都拦截
excludePath.add("/user/login");
excludePath.add("/swagger-ui.html");
excludePath.add("/webjars/**");
excludePath.add("/css/**");
excludePath.add("/js/**");
excludePath.add("/index.html");
excludePath.add("/doc.html");
excludePath.add("/swagger-resources/**");
excludePath.add("/v2/api-docs/**");
excludePath.add("favicon.ico");
registry.addInterceptor(tokenInterceptor)
.addPathPatterns("/**")
.excludePathPatterns(excludePath);
WebMvcConfigurer.super.addInterceptors(registry);
}
}
- 在handler文件包里创建TokenInterceptor
package com.example.hamlet.handler;
import com.alibaba.fastjson.JSONObject;
import com.example.hamlet.util.TokenUtil;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @ClassName TokenInterceptor
* @Description TODO
* @Author Hamlet
* @Date 2022/11/9 16:49
* @Version 1.0
*/
@Component
public class TokenInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//跨域请求会首先发一个option请求,直接返回正常状态并通过拦截器
if(request.getMethod().equals("OPTIONS")){
response.setStatus(HttpServletResponse.SC_OK);
return true;
}
//获取到token
String token = request.getHeader("token");
if (token!=null){
boolean result= TokenUtil.verify(token);
if (result){
System.out.println("通过拦截器");
return true;
}
}
try {
JSONObject json=new JSONObject();
json.put("msg","token verify fail");
json.put("code","500");
response.getWriter().append(json.toString());
System.out.println("认证失败,未通过拦截器");
} catch (Exception e) {
return false;
}
return false;
}
}
4、Util下创建TokenUtil
package com.example.hamlet.util;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.hamlet.entity.SystemUser;
import java.util.Date;
/**
* @ClassName TokenUtil
* @Description TODO
* @Author Hamlet
* @Date 2022/11/9 16:44
* @Version 1.0
*/
public class TokenUtil
{
//token到期时间60s
private static final long EXPIRE_TIME= 2*60*1000;
//密钥盐
private static final String TOKEN_SECRET="123456qwertyuiop789";
/**
* 创建一个token
* @param user
* @return
*/
public static String sign(SystemUser user){
String token=null;
try {
Date expireAt=new Date(System.currentTimeMillis()+EXPIRE_TIME);
token = JWT.create()
//发行人
.withIssuer("auth0")
//存放数据
.withClaim("userid",user.getId())
.withClaim("username",user.getName())
.withClaim("user account",user.getUserAccount())
//过期时间
.withExpiresAt(expireAt)
.sign(Algorithm.HMAC256(TOKEN_SECRET));
} catch (IllegalArgumentException | JWTCreationException je) {
}
return token;
}
/**
* 对token进行验证
* @param token
* @return
*/
public static Boolean verify(String token){
try {
//创建token验证器
JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("auth0").build();
DecodedJWT decodedJWT=jwtVerifier.verify(token);
System.out.println("认证通过:");
System.out.println("username: " + TokenUtil.getUserName(token));
System.out.println("过期时间: " + decodedJWT.getExpiresAt());
} catch (IllegalArgumentException | JWTVerificationException e) {
//抛出错误即为验证不通过
return false;
}
return true;
}
/**
* 获取用户名
*/
public static String getUserName(String token){
try{
DecodedJWT jwt=JWT.decode(token);
return jwt.getClaim("username").asString();
}catch (JWTDecodeException e)
{
return null;
}
}
}
控制器
1、除了登录,其他的都会拦截,如果想设置拦截的话,到config里维护即可
三、现在我们运行起来看看效果
直接运行接口的话就会返回
{"msg":"token verify fail","code":"500"}
成功的话返回:
{
"code": 200,
"msg": "操作成功",
"data": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIGFjY291bnQiOiJhZG1pbiIsImlzcyI6ImF1dGgwIiwiZXhwIjoxNjc1Njc4MDIxLCJ1c2VyaWQiOjE1LCJ1c2VybmFtZSI6ImFkbWluIn0.Cu-RWXMBRlnQfST_RpaZlYntbJ3lV7zIuL7UcrMzZP4"
}
此文完,关注作者不迷路,天天都走发财路!