1. Implement the annotation classes that skip authentication (PassToken) and require authentication (UserLoginToken)
@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; }
2. Implement getting Token class (TokenService)
@Service public class TokenService { public String getToken(User user) { // Expiration time, 5 minutes long EXPIRE_TIME = 5*60*1000; // Build expiration Date expireDate = new Date(System.currentTimeMillis()+EXPIRE_TIME); String token = JWT.create().withAudience(user.getId())// Save user id to token .withExpiresAt(expireDate)// Set expiration time .sign(Algorithm.HMAC256(user.getPassword()));// password as the key of token return token; } }
3. Implement the token authentication class (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");// Take token from http request header // If it is not mapped to a method directly through if(!(object instanceof HandlerMethod)){ return true; } HandlerMethod handlerMethod=(HandlerMethod)object; Method method=handlerMethod.getMethod(); //Check whether there is a passtoken comment, and skip authentication if there is one if (method.isAnnotationPresent(PassToken.class)) { PassToken passToken = method.getAnnotation(PassToken.class); if (passToken.required()) { return true; } } //Check for comments that require user rights if (method.isAnnotationPresent(UserLoginToken.class)) { UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class); if (userLoginToken.required()) { // Executive certification if (token == null) { throw new RuntimeException("Not signed in, please sign in"); } // Get user id in token String userId; try { userId = JWT.decode(token).getAudience().get(0); } catch (JWTDecodeException j) { throw new RuntimeException("token Wrong authentication name, please login again"); } User user = userService.findUserById(userId); if (user == null) { throw new RuntimeException("User does not exist, please login again"); } // Verify token JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build(); try { jwtVerifier.verify(token); } catch (JWTVerificationException e) { throw new RuntimeException("token The authentication password is wrong or the login has expired. Please login again"); } return true; } } 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 { } }
4. Because you need to throw an exception, implement a global exception capture class ()
@ControllerAdvice public class GloablExceptionHandler { @ResponseBody @ExceptionHandler(Exception.class) public Object handleException(Exception e) { String msg = e.getMessage(); if (msg == null || msg.equals("")) { msg = "Server error"; } JSONObject jsonObject = new JSONObject(); jsonObject.put("status", 500); jsonObject.put("message", msg); return jsonObject; } }
5. Add the InterceptorConfig to verify all the mapping paths
@Configuration public class InterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(authenticationInterceptor()) .addPathPatterns("/**"); // Block all requests, and determine whether to log in by judging whether there is @ UserLoginToken annotation } @Bean public AuthenticationInterceptor authenticationInterceptor() { return new AuthenticationInterceptor(); } }
6. Implement access class (UserController)
@RestController @RequestMapping("/api") public class UserController { @Autowired UserService userService; @Autowired TokenService tokenService; //Sign in @PostMapping("/login") public Object login(@RequestBody User user){ JSONObject jsonObject=new JSONObject(); User userForBase=userService.findUserById("user"); if(userForBase==null){ jsonObject.put("message","Login failed,user does not exist"); return jsonObject; }else { if (!userForBase.getPassword().equals(user.getPassword())){ jsonObject.put("message","Login failed,Password error"); return jsonObject; }else { String token = tokenService.getToken(userForBase); jsonObject.put("token", token); jsonObject.put("user", userForBase); return jsonObject; } } } @UserLoginToken @GetMapping("/getMessage") public Object getMessage(){ Map<String, Object> retMap = new HashMap<>(); retMap.put("message", "You have passed the verification"); retMap.put("status", 200); return retMap; } }
7. Post man access
* http://127.0.0.1:8080/api/login
* http://127.0.0.1:8080/api/getMessage
No access effect before login
Login successfully
Login succeeded with token access
Access after token error or login time expires
Source code address of github project
https://github.com/kenyonlover/spring_boot_jwt_test
Published 11 original articles, praised 0, visited 1645