SpringBoot整合JWT生成token及校驗方法過程解析
阿新 • • 發佈:2020-04-04
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,Object o,ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest httpServletRequest,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,返回失敗:
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。