Jwt初始 & session 比較

引言:最近看了一個開源項目,涉及了些比較陌生的東西,爲了加深印象,做點小筆記;

JWT

json web token,簡單來說,就是客戶端與服務器進行驗證的解決方案之一;另外一種就是使用session的方式;

使用原理:

當客戶端第一次登陸後,服務端會返回JWT格式的令牌,包含一些用戶的信息,客戶端則會保存這個JWT信息至Cookie或者其他數據層框架,用於下次登陸時驗證。
此時,服務端不需要去存儲任何當前用戶的信息。而下次請求時,客戶端都需要攜帶次JWT信息,客戶端則會去解析該信息,重新認證該用戶,授權該用戶;

使用方法:

項目權限認證使用的spring security框架,第一次登陸時,在相應的successHandle中添加成功處理邏輯:

  • 登陸成功生成JWT:
// jwt
            token = SecurityConstant.TOKEN_SPLIT + Jwts.builder()
                    //主題 放入用戶名
                    .setSubject(username)
                    //自定義屬性 放入用戶擁有請求權限
                    .claim(SecurityConstant.AUTHORITIES, new Gson().toJson(list))
                    //失效時間
                    .setExpiration(new Date(System.currentTimeMillis() + tokenExpireTime * 60 * 1000))
                    //簽名算法和密鑰
                    .signWith(SignatureAlgorithm.HS512, SecurityConstant.JWT_SIGN_KEY)
                    .compact();
              
                    ResponseUtil.out(response, ResponseUtil.resultMap(true,200,"登錄成功", token));

再次請求校驗jwt:
只需要在Jwt認證的過濾器中添加該校驗;

 private UsernamePasswordAuthenticationToken getAuthentication(String header, HttpServletResponse response) {
		// 用戶名
        String username = null;
        // 權限
        List<GrantedAuthority> authorities = new ArrayList<>();
            try {
                // 解析token
                Claims claims = Jwts.parser()
                        .setSigningKey(SecurityConstant.JWT_SIGN_KEY)
                        .parseClaimsJws(header.replace(SecurityConstant.TOKEN_SPLIT, ""))
                        .getBody();

                //獲取用戶名
                username = claims.getSubject();
                //獲取權限
                String authority = claims.get(SecurityConstant.AUTHORITIES).toString();

                if(StrUtil.isNotBlank(authority)){
                    List<String> list = new Gson().fromJson(authority, new TypeToken<List<String>>(){}.getType());
                    for(String ga : list){
                        authorities.add(new SimpleGrantedAuthority(ga));
                    }
                }
            } catch (ExpiredJwtException e) {
                ResponseUtil.out(response, ResponseUtil.resultMap(false,401,"登錄已失效,請重新登錄"));
            } catch (Exception e){
                log.error(e.toString());
                ResponseUtil.out(response, ResponseUtil.resultMap(false,500,"解析token錯誤"));
            }

比較Session

衆所周知,Session方式的用戶信息認證是將登陸信息存儲在服務器端,redis緩存中,或者持久化;
而在分佈式的系統中,就只能持久化;
另外,session方式返回給瀏覽器端的認證信息一般只需要一個id,而JWT是將複雜的用戶信息,甚至加密加長後返給客戶端,這可能讓存儲4k的Cookie比較難爲情了;以致於前端可能需要拓展另外的方案解決認證問題;

總結:
JWT是將用戶登錄信息存儲在客戶端的一種方便拓展的認證方案,而Session則是將用戶信息存儲在服務器端的更安全的解決方案;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章