SpringBoot 整合JWT
2019-03-07 本文已影响0人
木头就是我呀
JWT 是 JSON WEB TOKEN 的缩写
1.添加 POM 文件依赖
<!-- jwt -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
2.创建两个注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PassToken {
//通过验证
boolean required() default true;
}
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserLoginToken {
//需要登录验证
boolean required() default true;
}
3.创建 TokenService 实现类
@Service
public class TokenService {
/**
* 获取Token的方法.
*
* @param user user
* @return
*/
public String getToken(User user) {
String token = "";
//使用userName作为Token的内容
//使用password作为加密秘钥
token =
JWT.create()
.withAudience(user.getUserName().toString())
.sign(Algorithm.HMAC256(user.getPassword()));
return token;
}
}
- 编写Token拦截器
public class AuthenticationInterceptor implements HandlerInterceptor {
@Resource private UserService userService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 获取到Token
String token = request.getHeader("token");
// 如果不是映射方法那么就直接通过
if (!(handler instanceof HandlerMethod)) {
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
// 检查是否有passToken注解,有的话那么就跳过该验证
if (method.isAnnotationPresent(JwtApplication.PassToken.class)) {
JwtApplication.PassToken passToken = method.getAnnotation(JwtApplication.PassToken.class);
if (passToken.required()) {
return true;
}
}
// 检查有没有需要用户权限的注解
if (method.isAnnotationPresent(JwtApplication.UserLoginToken.class)) {
JwtApplication.UserLoginToken userLoginToken =
method.getAnnotation(JwtApplication.UserLoginToken.class);
if (userLoginToken.required()) {
// 执行认证
if (token == null) {
throw new RuntimeException("无Token 请重新登录");
}
// 获取Token中的userId
String userName;
try {
userName = JWT.decode(token).getAudience().get(0);
} catch (JWTDecodeException j) {
throw new RuntimeException("401");
}
User user = userService.getUserByUserName(userName);
if (user == null) {
throw new RuntimeException("该用户不存在 请重新登录");
}
// 验证Token
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
try {
jwtVerifier.verify(token);
} catch (JWTVerificationException j) {
throw new RuntimeException("401");
}
return true;
}
}
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 {}
}
- 编写拦截器配置项
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authenticationInterceptor()).addPathPatterns("/**");
}
@Bean
public AuthenticationInterceptor authenticationInterceptor() {
return new AuthenticationInterceptor();
}
}
6.Controller的代码
@RestController
public class LoginController implements LoginApi {
@Resource private UserService userService;
@Resource private TokenService tokenService;
@Override
public Map<String, Object> login(@RequestBody User user) {
Map<String, Object> result = new HashMap<>();
User user1 = userService.getUserByUserName(user.getUserName());
if (user1 == null) {
result.put("msg", "登录失败,用户不存在");
return result;
} else {
if (!user1.getPassword().equals(user.getPassword())) {
result.put("msg", "密码错误");
return result;
} else {
String token = tokenService.getToken(user);
result.put("token", token);
return result;
}
}
}
@JwtApplication.UserLoginToken
@Override
public String test() {
return "你已经通过该验证";
}
}
完成Token的配置
在单点登录系统中非常常见
前后端分离的系统中作为请求的令牌也非常常见