JWT实现拦截器和token认证
Jwt实现拦截器
·
一、导入依赖
Jwt全称为json web token,是跨域的支持各种语言、一般有三个部分头部(header)、载荷(payload)、签名(signature)
功能如下:
1.头部放签名算法和令牌类型
2.载荷放你想放的信息,如账号啥的,令牌之后就可以直接从这里获取信息不用再查数据库
3.签名放前两部分的签名,防止数据篡改
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.3</version>
</dependency>
二、使用教程
1.Jwt工具
import cn.hutool.core.date.DateUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import java.util.Date;
public class JwtUtils {
/**
* @param userId
* @param sign
* @return 以userId作为载荷,获取一个token
*/
public static String getToken(String userId, String password){
//将userId保存到token作为载荷
return JWT.create().withAudience(userId)
.withExpiresAt(DateUtil.offsetHour(new Date(),24))
.sign(Algorithm.HMAC256(password));
}
}
withAudience()可以放用户名、账户id之类的,这样就不用查询数据库了
withExpiresAt()放token的过期时间,上面的表示token24小时之后过期
sign()放签名认证,一般是放加密后的密码
2.拦截规则
import com.group.oayouth.Interceptor.JwtInterceptor;
import org.springframework.context.annotation.Bean;
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 {
@Bean
public JwtInterceptor jwtInterceptor(){
return new JwtInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/user/login","/user/register","/**/excel","/**/import");
}
}
addPathPatterns() 放要拦截的接口
excludePathPatterns()放开放的接口
上面代码的意思是拦截除了开放接口以外的所以接口
3.拦截器编写
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.group.oayouth.entity.User;
import com.group.oayouth.service.IUserService;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class JwtInterceptor implements HandlerInterceptor {
@Resource
private IUserService userService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 从 http 请求头中取出 token
String token = request.getHeader("token");
// 如果不是映射到方法直接通过
if(!(handler instanceof HandlerMethod)){
return true;
}
if (StringUtils.isBlank(token)) {
throw new RuntimeException("无token,请重新登录");
}
// 获取 token中的userId,根据userId查询数据库,检查用户是否存在
String userId;
try {
userId = JWT.decode(token).getAudience().get(0);
} catch (JWTDecodeException j) {
throw new RuntimeException("401");
}
User user = userService.getById(userId);
if (user == null) {
throw new RuntimeException("用户不存在,请重新登录");
}
// 验证 token
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
try {
jwtVerifier.verify(token);
} catch (JWTVerificationException e) {
throw new RuntimeException("token失效,请重新登录");
}
return true;
}
}
4.登录接口
这里自由发挥了图片仅供参考,把你的token放进进登录的实体类就行。
我这里密码用了md5加密,所以你的password放进token之前也要先加密一下
5.测试
调用没放行的接口出现以下情况说明成功,记得捕获异常哈
注意
你配置的swagger那些公共模块的网址也要放行,不然会被拦截掉
更多推荐
所有评论(0)