1.导入JWT依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.11.0</version>
</dependency>
2.添加JWT工具类
主要功能生成token
public class JwtUtil {
/**
* 过期时间5分钟
*/
private static final long EXPIRE_TIME = 5 * 60 * 1000;
/**
* jwt 密钥
*/
private static final String SECRET = "jwt_secret";
/**
* 生成签名,五分钟后过期
* @param userId
* @param info,Map的value只能存放的值的类型为:Map, List, Boolean, Integer, Long, Double, String and Date
* @return
*/
public static String sign(String userId,Map<String,Object> info) {
try {
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
Algorithm algorithm = Algorithm.HMAC256(SECRET);
return JWT.create()
// 将 user id 保存到 token 里面
.withAudience(userId)
// 存放自定义数据
.withClaim("info", info)
// 五分钟后token过期
.withExpiresAt(date)
// token 的密钥
.sign(algorithm);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 根据token获取userId
* @param token
* @return
*/
public static String getUserId(String token) {
try {
String userId = JWT.decode(token).getAudience().get(0);
return userId;
} catch (JWTDecodeException e) {
return null;
}
}
/**
* 根据token获取自定义数据info
* @param token
* @return
*/
public static Map<String,Object> getInfo(String token) {
try {
return JWT.decode(token).getClaim("info").asMap();
} catch (JWTDecodeException e) {
return null;
}
}
/**
* 校验token
* @param token
* @return
*/
public static boolean checkSign(String token) {
try {
Algorithm algorithm = Algorithm.HMAC256(SECRET);
JWTVerifier verifier = JWT.require(algorithm)
// .withClaim("username", username)
.build();
verifier.verify(token);
return true;
} catch (JWTVerificationException exception) {
throw new RuntimeException("token 无效,请重新获取");
}
}
}
3.设置JWT拦截器
public class JwtInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) {
// 如果不是映射到方法直接通过
if(!(object instanceof HandlerMethod)){
return true;
}
// 从 http 请求头中取出 token
String token = httpServletRequest.getHeader("token");
if (token == null) {
throw new RuntimeException("无token,请重新登录");
}
// 验证 token
JwtUtil.checkSign(token);
// 验证通过后,这里测试取出JWT中存放的数据
// 获取 token 中的 userId
String userId = JwtUtil.getUserId(token);
System.out.println("id:" + userId);
// 获取 token 中的 其他数据
Map<String, Object> info = JwtUtil.getInfo(token);
info.forEach((k,v)->System.out.println(k+":"+v));
return true;
}
}
4.设置要拦截的url
@Configuration
public class WebConfig implements WebMvcConfigurer {
/**
* 添加jwt拦截器,并指定拦截路径
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor())
.addPathPatterns("")//要拦截的url
.excludePathPatterns("/");//不是要拦截url
}
/**
* jwt拦截器
*/
@Bean
public JwtInterceptor jwtInterceptor() {
return new JwtInterceptor();
}
}
5.对Controller层设置需要输入token的请求
@Api(tags = "User")
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
UserService service;
//登录操作无需token
//登录成功返回token
@ApiOperation(value = "登录",notes = "传入用户名和密码")
@PostMapping("/login")
public Result login(String username,String password){
Map<String, Object> info = new HashMap<>();
User user = service.login(username, password);
info.put("username", user.getUsername());
info.put("realname", user.getRealname());
info.put("role",user.getRole().getId());
String token = JwtUtil.sign(Long.toString(user.getId()), info);
return Result.success("token: "+token);
}
//删除操作在登陆操作之后
//需要token
@ApiOperation(value = "通过Id删除用户",notes = "传入要删除对象的Id")
@ApiImplicitParams({
@ApiImplicitParam(name = "token",value = "JWT",
dataType = "String",required = true,
paramType = "header"),
})
@DeleteMapping("/deleteUserById/{id}")
public Result deleteUserById(@PathVariable Long id){
service.deleteUserById(id);
return Result.success("单个删除成功");
}
}