天天看點

JWT的原理與使用(包括與springboot整合)

文章目錄

    • 1.什麼是jwt
    • 2.jwt能做什麼
    • 3.jwt有何優勢
    • 4.jwt的結構
    • 5.JWT的使用
    • 6.封裝工具類
    • 7.整合springboot

1.什麼是jwt

JWT是JSON Web Token的簡寫,以Json形式做為web應用中的令牌,用于在各方之間安全地将資訊作為json對象傳輸,傳輸過程中可以完成資料加密、簽名等相關處理。

2.jwt能做什麼

1.授權。

2.資訊交換。

3.jwt有何優勢

傳統的session認證方式将session儲存在服務端(一般是記憶體),通過用戶端cookie的sessionid來找到對應的session實作認證。此方式有如下缺點:

1.随着認證使用者的增加,伺服器記憶體會随着增加。

2.如果session儲存在伺服器記憶體中,下次登入必須再次請求存session的伺服器才能進行認證,限制了應用的擴充能力。

3.cookie有被截獲的風險。

4.sessionid表達的資訊不豐富,不容易擴充。

jwt認證是将使用者資訊作為JWT Payload(負載),将其與頭部(header)分别進行Base64編碼拼接後簽名,形成一個jwt,格式為header.payload. signature(簽名)。

相對傳統的session認證,有如下優勢:

1.簡潔:可通過post參數或者在header中發送,資料小傳輸快。

2.自包含:負載中包含了所有使用者需要的資訊,避免多次查詢。

3.跨語言:因為是json加密的形式,基本适用任何web應用。

4.無須在服務端儲存,更适合分布式系統。

4.jwt的結構

1.标頭(header)

标頭由兩部分組成,令牌類型(預設jwt)和簽名算法 ,使用base64(可逆編碼,非加密)編成jwt的第一部分。

2.負載(payload)

包含了聲明,聲明是使用者相關實體和其它資料的聲明。同樣使用Base64編碼。

3.簽名(signature)

簽名是jwt的重點,由編碼後的标頭和負載加上密鑰再使用簽名算法(标頭中指定的算法)簽名後得出。

如果标頭中的簽名算法為a,編碼後的标頭為x,編碼後的負載為y,密鑰為z,簽名就是a(x+"."+y,z)。而整個jwt就是x.y.a(x+"."+y,z)。

值得注意的是因為負載的編碼可逆,負載裡不能存放敏感資訊。

5.JWT的使用

JWT的原理與使用(包括與springboot整合)
JWT的原理與使用(包括與springboot整合)
JWT的原理與使用(包括與springboot整合)
JWT的原理與使用(包括與springboot整合)
JWT的原理與使用(包括與springboot整合)
JWT的原理與使用(包括與springboot整合)

6.封裝工具類

public class JWTUtils {
    //密鑰
    private static final String SING="[email protected]#$%";

    /**
     * 生成token
     */
    public static String getToken(Map<String,String> map){
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.DATE,7); //7天過期

        //建立Builder
        JWTCreator.Builder builder = JWT.create();
        
        //payload
        map.forEach((k,v)->{
            builder.withClaim(k,v);
        });

        String toekn = builder.withExpiresAt(instance.getTime())//過期時間
                .sign(Algorithm.HMAC256(SING));//簽名
        return toekn;
    }

    /**
     * 驗證TOKEN
     */
    public static void verify(String token){
        JWT.require(Algorithm.HMAC256(SING)).build().verify(token);
    }

    /**
     * 擷取token資訊
     */
    public static DecodedJWT getTokenInfo(String token){
        DecodedJWT verify = JWT.require(Algorithm.HMAC256(SING)).build().verify(token);
        return verify;
    }
}

           

7.整合springboot

JWT的原理與使用(包括與springboot整合)
JWT的原理與使用(包括與springboot整合)
JWT的原理與使用(包括與springboot整合)
JWT的原理與使用(包括與springboot整合)
JWT的原理與使用(包括與springboot整合)
JWT的原理與使用(包括與springboot整合)
JWT的原理與使用(包括與springboot整合)
JWT的原理與使用(包括與springboot整合)
JWT的原理與使用(包括與springboot整合)
JWT的原理與使用(包括與springboot整合)
JWT的原理與使用(包括與springboot整合)

以上實作了token的驗證,但是每次都要傳遞token,可以用攔截器進行優化。

建立攔截類:

/**
 * JWT攔截器
 */
public class JWTInterceptor implements HandlerInterceptor {

    //處理請求前調用
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler) throws IOException {
        Map<String, Object> map = new HashMap<>();
        //擷取請求頭中的token
        String token = request.getHeader("token");

        try {
            JWTUtils.verify(token);
            return true; //放行
        } catch (SignatureVerificationException e) { //簽名異常
            e.printStackTrace();
            map.put("msg","無效簽名");
        }catch (TokenExpiredException e) { //有效期異常
            e.printStackTrace();
            map.put("msg","token過期");
        }catch (AlgorithmMismatchException e) { //算法異常
            e.printStackTrace();
            map.put("msg","算法不一緻");
        }catch (Exception e) {
            e.printStackTrace();
            map.put("msg","token無效");
        }
        map.put("state",false); //異常設定狀态
        String json = new ObjectMapper().writeValueAsString(map); //将對象轉換為Json字元串
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(json);
        return false;

    }
}
           

建立配置類:

/**
 * 攔截器配置類
 */
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry){
        registry.addInterceptor(new JWTInterceptor()) //攔截器
                .addPathPatterns("/user/test") //攔截器的路徑
                .excludePathPatterns("/user/login"); //不需要攔截的路徑
    }
}
           
JWT的原理與使用(包括與springboot整合)
JWT的原理與使用(包括與springboot整合)

繼續閱讀