目錄
JWT
會話跟蹤
token
響應攔截器
http是無狀態的,登錄成功后,客戶端就與服務器斷開連接,之后再向后端發送請求時,后端需要知道前端是哪個用戶在進行操作。
JWT
Json web token (JWT), 是為了在網絡應用環境間傳遞聲明而執行的一 種基于 JSON 的開放標準((RFC 7519).定義了一種簡潔的,自包含的方法用于通信雙方之間以 JSON 對象的形式安全的傳遞信息。
會話跟蹤
1. 用戶使用賬號和密碼發出 post 請求;
2. 服務器使用私鑰創建一個 jwt;
public class JWTUtil {/*** 根據用戶id,賬號生成token* @param admin* @return*/public static String getToken(Admin admin) {String token = "";try {//過期時間 為1970.1.1 0:0:0 至 過期時間 當前的毫秒值 + 有效時間Date expireDate = new Date(new Date().getTime() + 10*1000);//秘鑰及加密算法Algorithm algorithm = Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE");//設置頭部信息Map<String,Object> header = new HashMap<>();header.put("typ","JWT");header.put("alg","HS256");//攜帶id,賬號信息,生成簽名token = JWT.create().withHeader(header).withClaim("id",admin.getId()).withClaim("account",admin.getAccount()).withExpiresAt(expireDate).sign(algorithm);}catch (Exception e){e.printStackTrace();return null;}return token;}/*** 驗證token是否有效* @param token* @return*/public static boolean verify(String token){try {//驗簽Algorithm algorithm = Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE");JWTVerifier verifier = JWT.require(algorithm).build();DecodedJWT jwt = verifier.verify(token);return true;} catch (Exception e) {//當傳過來的token如果有問題,拋出異常return false;}}/*** 獲得token 中playload部分數據,按需使用* @param token* @return*/public static DecodedJWT getTokenInfo(String token){return JWT.require(Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE")).build().verify(token);}}
3. 服務器返回這個 jwt 給瀏覽器;
4. 瀏覽器將該 jwt 串在請求頭中像服務器發送請求;
5. 服務器驗證該 jwt;
6. 返回響應的資源給瀏覽器。
由于在每次的前后端交互過程中都需要進行token的驗證,為了降低代碼的冗余,可以借助過濾器來幫助我們完成這個工作。
public class AdminTokenFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest)servletRequest;String adminToken = request.getHeader("adminToken");boolean verify = JWTUtil.verify(adminToken);if(verify){filterChain.doFilter(servletRequest, servletResponse);}else {//token驗證失敗servletResponse.setContentType("text/html;charset=utf-8");PrintWriter printWriter = servletResponse.getWriter();CommonResult commonResult = new CommonResult(401, "token驗證失敗");ObjectMapper objectMapper = new ObjectMapper();String json = objectMapper.writeValueAsString(commonResult);printWriter.write(json);}}
}
token
1.將后端封裝好的信息發送給前端
2.前端接收后存儲在sessionStorage對象中
3.在后面每次發送請求時都將token放入請求頭中發送到后端進行驗證
4.后端在對token進行解析
響應攔截器
如果token驗證失敗,后端向前端傳回一個標識用于告訴前端token驗證失敗
在前端main.js中添加攔截器
// 添加響應攔截器
axios.interceptors.response.use((resp) => { //正常響應攔截if (resp.data.code == 500) {ElementUI.Message({message: resp.data.message,type: "error"})}if (resp.data.code == 401) {//自定義的狀態碼ElementUI.Message({message: "token驗證失敗",type: "error"})router.replace("/login");}return resp;
});
這樣每次前端進行操作時都會先驗證token