基於Token的身份認證方法
1.基於 Token 的身份驗證方法
使用基於 Token 的身份驗證方法,在服務端不需要儲存使用者的登入記錄。大概的流程是這樣的:
- 客戶端使用使用者名稱跟密碼請求登入
- 服務端收到請求,去驗證使用者名稱與密碼
- 驗證成功後,服務端會簽發一個 Token,再把這個 Token 傳送給客戶端
- 客戶端收到 Token 以後可以把它儲存起來,比如放在 Cookie 裡或者 Local Storage 裡
- 客戶端每次向服務端請求資源的時候需要帶著服務端簽發的 Token
- 服務端收到請求,然後去驗證客戶端請求裡面帶著的 Token,如果驗證成功,就向客戶端返回請求的資料
2.程式碼示例
2.1、使用者登入成功後,以token作為key將使用者資訊放到redis中並返回,返回的使用者資訊中也包括token。
UserDTO userDTO = new UserDTO(); userDTO.setCode(loginUser.getCode()); userDTO.setName(loginUser.getName()); userDTO.setDeptCode(loginUser.getDeptCode()); userDTO.setDeptName(loginUser.getDeptName()); userDTO.setRoles(roles); userDTO.setAuthoritys(authoritys); // redis中存放的key token = CodeUtil.getCode();//UUID生成 userDTO.setToken(token); // 存放redis,暫時2小時 redis.set(token, JsonUtils.objectToJson(userDTO), 7200); //返回加密後的資訊 encoder.encodeToString(JsonUtils.objectToJson(userDTO).getBytes("UTF-8")) |
2.2、後臺通過token從redis中獲取請求使用者資訊。
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String token = request.getHeader("token"); if (StringUtils.isEmpty(token)) { return null; } String userRedis = (String) redis.get(token); if (StringUtils.isEmpty(userRedis)) { return null; } UserDTO userFromRedis = JsonUtils.jsonToPojo(userRedis, UserDTO.class); |
2.3、token驗證攔截器
@Aspect public Object loginVerify(ProceedingJoinPoint joinPoint) throws Throwable{ } |
3.小結
- 如果API設計成規範的無狀態RESTful,考慮使用token
- 如果API被不同終端消費,Cookie受限,考量token
- cookie存在瀏覽器,不安全;
- session存在伺服器,可能影響效能;
- token身份認證安全性好,是唯一的。