qidao123.com技术社区-IT企服评测·应用市场

标题: Web身份认证 --- Session和JWT Token [打印本页]

作者: 小小小幸运    时间: 2024-12-27 00:39
标题: Web身份认证 --- Session和JWT Token
方法一: 通过使用Session进行身份认证

   
     
    使用SpringBoot实现简朴的session + cookie实现持久登录
   
  1. @PostMapping("login")
  2.     public JsonData login(@RequestBody User user, HttpServletRequest request, HttpServletResponse response) {
  3.         String crypPassword = MD5Utils.MD5(user.getPwd());
  4.         User loggedinUser = userService.login(user.getPhone(),  crypPassword);
  5.         if (loggedinUser != null) {
  6.                 //随机生成一个UUID作为seesion ID
  7.             String sessionID = UUID.randomUUID().toString();
  8.             //在服务器中将sessionID和用户组成 KV pair: Map<sessionID, USER>
  9.             //setAttribute的底层实现是一个hashmap
  10.             request.getSession().setAttribute(sessionID, loggedinUser);
  11.             //生成一个cookie, 并将sessionID加入cookie, 对应的名字是 "sessionId"
  12.             Cookie cookie = new Cookie("sessionId", sessionID);
  13.             cookie.setPath("/");
  14.             cookie.setMaxAge(FIVE_DAYS);
  15.             //在response中给客户端返回cookie
  16.             response.addCookie(cookie);
  17.             return JsonData.buildSuccess(loggedinUser);
  18.         }
  19.         return JsonData.buildError("Password or username invalid");
  20.     }
复制代码
  
  1. public static int currentUserID = -1;
  2. String sessionId = "Default";
  3. Cookie[] cookies = request.getCookies();
  4. if (cookies == null) {
  5.         System.out.println("Intercepter: No Cookies");
  6.            sendJsonMessage(response, JsonData.buildError("Interceptor: No Cookies, please log in first"));
  7.     currentUserID = -1;
  8.     return false;
  9. }
  10.                
  11. //遍历前端传来的cookie
  12. for (Cookie cookie: cookies) {
  13.         //如果发现 sessionId字段, 则说明发现sessionID
  14.     if (cookie.getName().equals("sessionId")) {
  15.             System.out.println("Interceptor: found a session id in cookie:" +  cookie.getValue());
  16.             //拿到sessionId
  17.         sessionId = cookie.getValue();
  18.         break;
  19.     }
  20. }
  21. //通过sessionID拿到user
  22. User user = (User)request.getSession().getAttribute(sessionId);
  23. if (sessionId.equals("Default") ||  user == null) {
  24.         System.out.println("Interceptor: sessionId not match, cannot preceed");
  25.     sendJsonMessage(response, JsonData.buildError("Interceptor: No record of this sessionID, please log in first"));
  26.     currentUserID = -1;
  27.     return false;
  28. }
  29. //拿到userID, 在别的类中可以通过 int uid = LoginInterceptor.currentUserID; 拿到uid
  30. currentUserID = user.getId();
复制代码
  
  方法二: 通过JWT token进行身份认证

什么是JWT

   
  Header
   
  1. {
  2.   "alg": "HS256",
  3.   "typ": "JWT"
  4. }
复制代码
Payload
   
  1. {
  2.   "sub": "666666",
  3.   "name": "warriors",
  4.   "admin": true
  5. }
复制代码
Signature
   
  1. HMACSHA256(
  2.   base64UrlEncode(header) + "." +
  3.   base64UrlEncode(payload),
  4.   secret)
复制代码
JWT完整流程

   
  用户登录
   
  天生JWT
   
  Header: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
   
  1. {
  2.         "alg": "HS256",
  3.         "typ": "JWT"
  4. }
复制代码
  
  Payload: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
   
  1. {
  2.         "sub": "1234567890",
  3.         "name": "John Doe",
  4.         "iat": 1516239022
  5. }
复制代码
  
  Signature: SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
   
  1. eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
复制代码
  
  1. header_payload = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
  2. "secret = "secret"signature = hmac.new(secret.encode(), header_payload.encode(), hashlib.sha256).digest()signature_base64 = base64.urlsafe_b64encode(signature).rstrip(b'=').decode()print(signature_base64)
复制代码
  
   
  返回JWT
   
  携带JWT进行哀求
   
  服务器验证JWT
   
  响应哀求
   
  JWT攻防

常见攻击方法
   
  防御措施
   
  JWT 怎样退出登录

JWT一旦发出,不能撤回,所以在有用期内会不停有用,常见退出方法有三种
   
  JWT的续签

   
     
    访问令牌(Access Token)
   
  刷新令牌(Refresh Token)
   
  为什么需要两个token
起首确认一点: token使用的次数越多被盗取概率越大,过期时间越长也就越危险
   
     
      
      
      
       使用两个token续签:
   
     

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/) Powered by Discuz! X3.4