SpringBoot集成JWT生成token及校验方法过程解析

 更新时间:2020年04月02日 15:04:03   作者:陌生街中吹起褪色故梦  
这篇文章主要介绍了SpringBoot集成JWT生成token及校验方法过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

GitHub源码地址:https://github.com/zeng-xian-guo/springboot_jwt_token.git

封装JTW生成token和校验方法

public class JwtTokenUtil {

  //公用密钥-保存在服务端,客户端是不会知道密钥的,以防被攻击
  public static String SECRET = "ThisIsASecret";

  //生成Troke
  public static String createToken(String username) {
    //签发时间
    //Date iatDate = new Date();
    //过地时间 1分钟后过期
    //Calendar nowTime = Calendar.getInstance();
    //nowTime.add(Calendar.MINUTE, 1);
    //Date expiresDate = nowTime.getTime();
    Map<String, Object> map = new HashMap();
    map.put("alg", "HS256");
    map.put("typ", "JWT");
    String token = JWT.create()
          .withHeader(map)
          //.withClaim( "name","Free码生") //设置 载荷 Payload
          //.withClaim("age","12")
          //.withClaim( "org","测试")
          //.withExpiresAt(expiresDate)//设置过期时间,过期时间要大于签发时间
          //.withIssuedAt(iatDate)//设置签发时间
          .withAudience(username) //设置 载荷 签名的观众
          .sign(Algorithm.HMAC256(SECRET));//加密
    System.out.println("后台生成token:" + token);
    return token;
  }

  //校验TOKEN
  public static boolean verifyToken(String token) throws UnsupportedEncodingException{
    JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
    try {
      verifier.verify(token);
      return true;
    } catch (Exception e){
      return false;
    }
  }

  //获取Token信息
  public static DecodedJWT getTokenInfo(String token) throws UnsupportedEncodingException{
    JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
    try{
      return verifier.verify(token);
    } catch(Exception e){
      throw new RuntimeException(e);
    }
  }

}

新建自定义注解:@UserLoginToken

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserLoginToken {
  boolean required() default true;
}

关于拦截器配置:

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(authenticationInterceptor())
        .addPathPatterns("/**");  // 拦截所有请求,通过判断是否有 @LoginRequired 注解 决定是否需要登录
  }
  @Bean
  public AuthenticationInterceptor authenticationInterceptor() {
    return new AuthenticationInterceptor();
  }
}
public class AuthenticationInterceptor implements HandlerInterceptor {
  @Autowired
  UserService userService;
  @Override
  public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
    String token = httpServletRequest.getHeader("token");// 从 http 请求头中取出 token
    // 如果不是映射到方法直接通过
    if(!(object instanceof HandlerMethod)){
      return true;
    }
    HandlerMethod handlerMethod=(HandlerMethod)object;
    Method method=handlerMethod.getMethod();
    //检查是否有passtoken注释,有则跳过认证
    if (method.isAnnotationPresent(PassToken.class)) {
      PassToken passToken = method.getAnnotation(PassToken.class);
      if (passToken.required()) {
        return true;
      }
    }
    //检查有没有需要用户权限的注解
    if (method.isAnnotationPresent(UserLoginToken.class)) {
      UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class);
      if (userLoginToken.required()) {
        // 执行认证
        if (token == null) {
          throw new RuntimeException("无token,请重新登录");
        }
        // 验证 token
        if(JwtTokenUtil.verifyToken(token)){
          return true;
        }else {
          throw new RuntimeException("401");
        }
      }
    }
    return true;
  }
  @Override
  public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
  }
  @Override
  public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
  }
}

登录:

在Controller上登录方法不用添加@UserLoginToken自定义注解,其余获取后台数据方法加上@UserLoginToken自定义注解,目的验证token是否有效,是则返回数据,否则提示401无权限。

测试:

@Controller
@RequestMapping(path = "/api")
public class IndexController {

  private String prefix = "index/";

  @GetMapping("/index")
  public String index()
  {
    return prefix + "index";
  }

  @UserLoginToken
  @PostMapping("/test")
  @ResponseBody
  public Object test(){
    Map<String,Object> map = new HashMap<>();
    map.put("code","200");
    map.put("message","你已通过验证了");
    return map;
  }
}

HTTP请求带上登陆成功后生成token,返回成功:

HTTP请求带上无效token或不带token,返回失败:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 继承jpa Repository 写自定义方法查询实例

    继承jpa Repository 写自定义方法查询实例

    这篇文章主要介绍了继承jpa Repository 写自定义方法查询实例,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Java基础概述面试题复习

    Java基础概述面试题复习

    这篇文章主要介绍了java基础面试题,文中的描述非常详细,对正在学习java基础的小伙伴们有非常好的帮助,需要的朋友可以参考下,希望能给你带来帮助
    2021-08-08
  • Spring Retry重试框架的使用讲解

    Spring Retry重试框架的使用讲解

    重试的使用场景比较多,比如调用远程服务时,由于网络或者服务端响应慢导致调用超时,此时可以多重试几次。用定时任务也可以实现重试的效果,但比较麻烦,用Spring Retry的话一个注解搞定所有,感兴趣的可以了解一下
    2022-10-10
  • Java并发编程之详解CyclicBarrier线程同步

    Java并发编程之详解CyclicBarrier线程同步

    在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口,ArrayBlockingQueue,DelayQueue,LinkedBlockingQueue,PriorityBlockingQueue,SynchronousQueue,BlockingDeque接口,ConcurrentHashMap,CountDownLatch,本文为系列文章第十篇,需要的朋友可以参考下
    2021-06-06
  • 解决Error:(1, 1) java: 非法字符: '\ufeff'问题

    解决Error:(1, 1) java: 非法字符: '\ufeff'问题

    这篇文章主要介绍了解决Error:(1, 1) java: 非法字符: '\ufeff'问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Java常用类之System类的使用指南

    Java常用类之System类的使用指南

    System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。该类位于java.lang包。本文将通过示例为大家详细讲讲System类的使用,需要的可以参考一下
    2022-07-07
  • bootstrap.yml如何读取nacos配置中心的配置文件

    bootstrap.yml如何读取nacos配置中心的配置文件

    这篇文章主要介绍了bootstrap.yml读取nacos配置中心的配置文件问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • idea远程调试spark的步骤讲解

    idea远程调试spark的步骤讲解

    今天小编就为大家分享一篇关于idea远程调试spark的步骤讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • 教你用IDEA配置JUnit并进行单元测试

    教你用IDEA配置JUnit并进行单元测试

    今天教各位小伙伴怎么用IDEA配置JUnit并进行单元测试,文中有非常详细的图文介绍及代码示例,对正在学习IDEA的小伙伴有很好的帮助,需要的朋友可以参考下
    2021-05-05
  • SpringSecurity安全框架在SpringBoot框架中的使用详解

    SpringSecurity安全框架在SpringBoot框架中的使用详解

    在Spring Boot框架中,Spring Security是一个非常重要的组件,它可以帮助我们实现应用程序的安全性,本文将详细介绍Spring Security在Spring Boot框架中的使用,包括如何配置Spring Security、如何实现身份验证和授权、如何防止攻击等
    2023-06-06

最新评论