Springboot-JWT token實現登陸
JWT認證過程:
(上圖)java
1.pom.xml
<dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.4.0</version> </dependency>
2.annotation(定義註解標識)
/** * 用來跳過驗證的PassToken * @author Mr. Cheng * @version 1.0 * @date 2020/10/9 0009 17:15 */ @Target({ ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface PassToken { boolean required() default true; }
/** * @author Mr. Cheng * @version 1.0 * @date 2020/10/9 0009 17:15 */ /** * 須要登陸才能進行操做的註解UserLoginToken */ @Target({ ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface UserLoginToken { boolean required() default true; }
3.config
- 先定義一個生成Token 的方法
@Service("TokenService") public class TokenService { public String getToken(User user) { String token=""; token= JWT.create().withAudience(user.getId())// 將 user id 保存到 token 裏面 .sign(Algorithm.HMAC256(user.getPassword()));// 以 password 做爲 token 的密鑰 return token; } }
- 配置攔截請求
@Configuration public class InterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(authenticationInterceptor()) .addPathPatterns("/**"); // 攔截全部請求,經過判斷是否有 @LoginRequired 註解 決定是否須要登陸 } @Bean public AuthenticationInterceptor authenticationInterceptor() { return new AuthenticationInterceptor(); } }
4.Interceptor
/** * 攔截器: 攔截全部請求 * @author Mr. Cheng * @version 1.0 * @date 2020/10/9 0009 17:14 */ 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 中的 user id String userId; try { userId = JWT.decode(token).getAudience().get(0); } catch (JWTDecodeException j) { throw new RuntimeException("401"); } User user = userService.findUserById(userId); if (user == null) { throw new RuntimeException("用戶不存在,請從新登陸"); } // 驗證 token JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build(); try { jwtVerifier.verify(token); } catch (JWTVerificationException e) { throw new RuntimeException("401"); } 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 { } }
5.entity
public class User { String Id; String username; String password; public String getId() { return Id; } public void setId(String id) { Id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } } }
6.mapper
public interface UserMapper { User findByUsername(@Param("username") String username); User findUserById(@Param("Id") String Id); }
7.service
@Service("UserService") public class UserService { @Autowired UserMapper userMapper; public User findByUsername(User user){ return userMapper.findByUsername(user.getUsername()); } public User findUserById(String userId) { return userMapper.findUserById(userId); } }
8.controller
/** * @author Mr. Cheng * @version 1.0 * @date 2020/10/9 0009 17:14 */ publi @RestController @RequestMapping("user") public class UserController { @Autowired UserService userService; @Autowired TokenService tokenService; //登陸 @PostMapping("/login") public Object login( User user){ JSONObject jsonObject=new JSONObject(); User userForBase=userService.findByUsername(user); if(userForBase==null){ jsonObject.put("message","登陸失敗,用戶不存在"); return jsonObject; }else { if (!userForBase.getPassword().equals(user.getPassword())){ jsonObject.put("message","登陸失敗,密碼錯誤"); return jsonObject; }else { String token = tokenService.getToken(userForBase); jsonObject.put("token", token); jsonObject.put("user", userForBase); return jsonObject; } } } @UserLoginToken @GetMapping("/getMessage") public String getMessage(){ return "你已經過驗證"; } }