当前位置:   article > 正文

SpringBoot使用JWT作为Token实现前后端分离登录_springboot jwt token前后端分离

springboot jwt token前后端分离

JWT就不多介绍了

传统的shiro和SpringSecurity安全框架需要Session,重启后Session会丢失,或者将Session存入redis也行,但是相对比较繁琐。利用JWT可以很轻松的实现Token的认证,在前后端分离的情况下,JWT也显得非常的简易。

依赖

  1. <dependency>
  2. <groupId>com.auth0</groupId>
  3. <artifactId>java-jwt</artifactId>
  4. <version>3.4.0</version>
  5. </dependency>

 

登录请求生成token,第一个参数传入ID,表明是哪个用户,第二个参数是对token进行加密,我们都用密码进行加密。

  1. String token = JWT.create().withAudience(user.getId() + "")
  2. .sign(Algorithm.HMAC256(user.getPwd()));

 

写一个notoken注解,此注解适用于方法上,用来表明某个请求不需要token

  1. @Target({ ElementType.METHOD, ElementType.TYPE })
  2. @Retention(RetentionPolicy.RUNTIME)
  3. public @interface NoToken {
  4. boolean required() default true;
  5. }

 

然后利用拦截器进行拦截所有的请求

  1. public class AuthenticationInterceptor implements HandlerInterceptor {
  2. @Autowired
  3. private UserMapper userMapper;
  4. @Override
  5. public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
  6. Object object) throws Exception {
  7. // 如果不是映射到方法直接通过
  8. if (!(object instanceof HandlerMethod)) {
  9. return true;
  10. }
  11. HandlerMethod handlerMethod = (HandlerMethod) object;
  12. Method method = handlerMethod.getMethod();
  13. // 检查是否有passtoken注释,有则跳过认证
  14. if (method.isAnnotationPresent(NoToken.class)) {
  15. NoToken passToken = method.getAnnotation(NoToken.class);
  16. if (passToken.required()) {
  17. return true;
  18. }
  19. } else {
  20. String token = httpServletRequest.getHeader("Authorization");
  21. // Token不存在
  22. if (token == null) {
  23. throw new NeedLoginException();
  24. }
  25. // 获取用户ID,如果出错抛异常
  26. Integer userId;
  27. try {
  28. userId = AuthUtils.getUserId(httpServletRequest);
  29. } catch (JWTDecodeException j) {
  30. throw new NeedLoginException();
  31. }
  32. Staff user = userMapper.selectByPrimaryKey(userId);
  33. if (user == null) {
  34. throw new NeedLoginException();
  35. }
  36. // 验证Token是否有效
  37. JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getStaffPwd() + "")).build();
  38. try {
  39. jwtVerifier.verify(token);
  40. } catch (JWTVerificationException e) {
  41. throw new NeedLoginException();
  42. }
  43. return true;
  44. }
  45. return true;
  46. }
  47. @Override
  48. public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
  49. ModelAndView modelAndView) throws Exception {
  50. }
  51. @Override
  52. public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
  53. Object o, Exception e) throws Exception {
  54. }
  55. }

 

将拦截器加入到Bean中

  1. @Configuration
  2. public class InterceptorConfig extends WebMvcConfigurerAdapter {
  3. @Override
  4. public void addInterceptors(InterceptorRegistry registry) {
  5. registry.addInterceptor(authenticationInterceptor()).addPathPatterns("/**"); // 拦截所有请求,通过判断是否有 @LoginRequired 注解
  6. }
  7. @Bean
  8. public AuthenticationInterceptor authenticationInterceptor() {
  9. return new AuthenticationInterceptor();
  10. }
  11. }

 

从请求头获取Token解析用户ID

  1. public class AuthUtils {
  2. public static Integer getUserId(HttpServletRequest req) {
  3. String token = req.getHeader("Authorization");
  4. String userId = JWT.decode(token).getAudience().get(0);
  5. return Integer.parseInt(userId);
  6. }
  7. }

 

这样就可以实现登录了。

如果有哪些请求不需要Token的话,直接可以加上注解@NoToken,在拦截器中判断如果遇到此注解,则不会进行判断Token

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/638496
推荐阅读
相关标签
  

闽ICP备14008679号