欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JWT全面解讀和詳細(xì)使用步驟

 更新時(shí)間:2021年12月02日 11:36:04   作者:丁可樂  
這篇文章全面解讀了JWT規(guī)范和詳細(xì)使用步驟,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

定義:JSON Web Token(縮寫 JWT)是目前最流行的跨域認(rèn)證解決方案

JWT官網(wǎng)

由于HTTP協(xié)議是無狀態(tài)的,這意味著如果我們想判定一個(gè)接口是否被認(rèn)證后訪問,就需要借助cookie或者session會(huì)話機(jī)制進(jìn)行判定,但是由于現(xiàn)在的系統(tǒng)架構(gòu)大部分都不止一臺(tái)服務(wù)器,此時(shí)又要借助數(shù)據(jù)庫或者全局緩存 做存儲(chǔ),這種方案顯然受限太多。

那么我們可不可以讓認(rèn)證令牌的發(fā)布者自己去識(shí)別這個(gè)令牌是不是我曾經(jīng)發(fā)布的令牌呢(JWT核心思想),這是JWT最大的優(yōu)點(diǎn)也是最大的缺點(diǎn),優(yōu)點(diǎn)是簡單快捷、不需要依賴任何第三方操作就能實(shí)現(xiàn)身份認(rèn)證,缺點(diǎn)就是對(duì)于任何擁有用戶發(fā)布令牌的請(qǐng)求都會(huì)認(rèn)證通過。

JWT的數(shù)據(jù)結(jié)構(gòu)

正常的JWT數(shù)據(jù)結(jié)構(gòu)應(yīng)該如下

它是一個(gè)很長的字符串,中間用點(diǎn)(.)分隔成三個(gè)部分

JWT的三個(gè)部分依次: Header - 頭部 、Payload - 負(fù)載 、Signature(簽名)

即:Header.Payload.Signature

Header

Header 部分是一個(gè) JSON 對(duì)象,描述 JWT 的元數(shù)據(jù),通常是下面的樣子。

{
"alg": "HS256",
"typ": "JWT"
}

alg屬性表示簽名的算法(algorithm),默認(rèn)是 HMAC SHA256(寫成 HS256);typ屬性表示這個(gè)令牌(token)的類型(type),JWT 令牌統(tǒng)一寫為JWT

Payload

Payload 部分也是一個(gè) JSON 對(duì)象,用來存放實(shí)際需要傳遞的數(shù)據(jù)。JWT 規(guī)定了7個(gè)官方字段,供選用。

  1. iss (issuer):簽發(fā)人
  2. exp (expiration time):過期時(shí)間
  3. sub (subject):主題
  4. aud (audience):受眾
  5. nbf (Not Before):生效時(shí)間
  6. iat (Issued At):簽發(fā)時(shí)間
  7. jti (JWT ID):編號(hào)

除了官方字段,你還可以在這個(gè)部分定義私有字段

{
"sub": "1234567890",
"name": "John Doe",
"age": "19"
}

注意:JWT默認(rèn)是明文展示,任何人都可以讀取到,所以此處不要放私密信息

這個(gè) JSON 對(duì)象也要使用 Base64URL 算法轉(zhuǎn)成字符串。

Signature

Signature 部分是對(duì)前兩部分的簽名,防止數(shù)據(jù)篡改。

首先,需要指定一個(gè)密鑰(secret)。這個(gè)密鑰只有服務(wù)器才知道,不能泄露給用戶。然后,使用 Header 里面指定的簽名算法(默認(rèn)是 HMAC SHA256),按照下面的公式產(chǎn)生簽名。

  HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

算出簽名以后,把 Header、Payload、Signature 三個(gè)部分拼成一個(gè)字符串,每個(gè)部分之間用"點(diǎn)"(.)分隔,就可以返回給用戶。

Base64URL

前面提到,Header 和 Payload 串型化的算法是 Base64URL。這個(gè)算法跟 Base64 算法基本類似,但有一些小的不同。

JWT 作為一個(gè)令牌(token),有些場合可能會(huì)放到 URL(比如 api.example.com/?token=xxx)。Base64 有三個(gè)字符+、/和=,在 URL 里面有特殊含義,所以要被替換掉:=被省略、+替換成-,/替換成_ 。這就是 Base64URL 算法

JWT的實(shí)現(xiàn)

Maven依賴

 <dependency>
		    <groupId>com.auth0</groupId>
		    <artifactId>java-jwt</artifactId>
		    <version>3.5.0</version>
</dependency>

JWT簽名發(fā)布和驗(yàn)證代碼

public class TokenUtil {
	//Token的過期時(shí)間
	private static final long EXPIRE_TIME = 30 * 60 * 1000;
	//Token的私鑰
	private static final String TOKEN_SECRET = "jytoken_secret";
	
	
	/**
	 * 生成簽名,30分鐘過期
	 * @param **userInfo**	用戶信息 用戶姓名
	* @param **other** 用戶其他信息 用戶id
	* @return
	 */
	public static String sign(String userInfo, String other) {
	    try {
	    	// 設(shè)置過期時(shí)間
	    	Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
	    	//私鑰和加密算法
	        Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
	        // 設(shè)置頭部信息
	        Map<String, Object> header = new HashMap<>(2);
	        header.put("Type", "Jwt");
	        header.put("alg", "HS256");
	        // 返回token字符串
	        return JWT.create()
	                .withHeader(header)
	                .withClaim("userInfo", userInfo)
	                .withClaim("other", other)
	                .withExpiresAt(date)
	                .sign(algorithm);
	    } catch (Exception e) {
	        e.printStackTrace();
	        return null;
	    }
	}
	
	/**
	 * 生成簽名,30分鐘過期
	 * @param **userInfo**	用戶信息 用戶姓名
	* @param **other** 用戶其他信息 用戶id
	* @return
	 */
	public static String sign(String userInfo, String other,long expire) {
	    try {
	    	// 設(shè)置過期時(shí)間
	    	Date date = new Date(System.currentTimeMillis() + expire);
	    	//私鑰和加密算法
	        Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
	        // 設(shè)置頭部信息
	        Map<String, Object> header = new HashMap<>(2);
	        header.put("Type", "Jwt");
	        header.put("alg", "HS256");
	        // 返回token字符串
	        return JWT.create()
	                .withHeader(header)
	                .withClaim("userInfo", userInfo)
	                .withClaim("other", other)
	                .withExpiresAt(date)
	                .sign(algorithm);
	    } catch (Exception e) {
	        e.printStackTrace();
	        return null;
	    }
	}
	
	
	/**
	 * 檢驗(yàn)token是否正確
	 * @param **token**
	* @return
	 */
	public static boolean verify(String token){
	    try {
	        Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
	        JWTVerifier verifier = JWT.require(algorithm).build();
	        verifier.verify(token);//未驗(yàn)證通過會(huì)拋出異常
	        return true;
	    } catch (Exception e){
	        return false;
	    }
	}
	
	/**
	 * 從token中獲取info信息
	 * @param **token**
	* @return
	 */
	public static String getUserName(String token,String info){
	    try {
	        DecodedJWT jwt = JWT.decode(token);
	        return jwt.getClaim(info).asString();
	    } catch (JWTDecodeException e){
	        e.printStackTrace();
	    }
	    return null;
	}
	
}

攔截器配置無需認(rèn)證的請(qǐng)求

@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport  {
   
	@Autowired
	private TokenHandler tokenHandler;
    


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        List<String> excludePath = new ArrayList<>();
        String checkLogin = "/pushlogin/checkIsCanLogin";
        String login = "/pushlogin/login";
        String getVerifyCode = "/common/send";
        String verfifyMethod = "/common/validationCode";
        excludePath.add(checkLogin);
        excludePath.add(login);
        excludePath.add(getVerifyCode);
        excludePath.add(verfifyMethod);
        registry.addInterceptor(tokenHandler).excludePathPatterns(excludePath);
    }
}

Token統(tǒng)一攔截器代碼

@Component
@Slf4j
public class TokenHandler implements HandlerInterceptor{
	
		@Override
	   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)  throws Exception {
	 
	        String token = request.getHeader("Authentication");
	        if (token != null){
	            boolean result = TokenUtil.verify(token);
	            if(result){
	                log.info("通過攔截器");
	                return true;
	            }
	        }
	        log.info("認(rèn)證失敗");
	        
	        return false;
	   }
	
}

用戶登錄時(shí)驗(yàn)證用戶信息后,返回Token信息

 	@Override
    public UserDTO selectIsExistUserInfo(String phone) {
        //TODO 偽代碼 驗(yàn)證用戶信息 
        UserDTO info = 查詢用戶信息
        if (info != null) {
            String token = TokenUtil.sign(info.getUsername(), info.getUserId(), 6 * 60 * 60 * 1000);
            info.setToken(token);
        }
        return info;
    }

到此這篇關(guān)于JWT全面解讀和詳細(xì)使用步驟的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java代碼如何判斷l(xiāng)inux系統(tǒng)windows系統(tǒng)

    Java代碼如何判斷l(xiāng)inux系統(tǒng)windows系統(tǒng)

    這篇文章主要介紹了Java代碼如何判斷l(xiāng)inux系統(tǒng)windows系統(tǒng)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • 淺談Java中真的只有值傳遞么

    淺談Java中真的只有值傳遞么

    這篇文章主要介紹了淺談Java中真的只有值傳遞么?文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • Spring中的AutowireCandidateResolver的具體使用詳解

    Spring中的AutowireCandidateResolver的具體使用詳解

    這篇文章主要介紹了Spring中的AutowireCandidateResolver的具體使用詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • Logger.getLogger()與LogFactory.getLog()的區(qū)別詳解

    Logger.getLogger()與LogFactory.getLog()的區(qū)別詳解

    LogFactory來自common-logging包。如果用LogFactory.getLog,你可以用任何實(shí)現(xiàn)了通用日志接口的日志記錄器替換log4j,而程序不受影響
    2013-09-09
  • 抽象類使用Jackson序列化問題

    抽象類使用Jackson序列化問題

    這篇文章主要介紹了抽象類使用Jackson序列化問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • 如何修改json字符串中某個(gè)key對(duì)應(yīng)的value值

    如何修改json字符串中某個(gè)key對(duì)應(yīng)的value值

    這篇文章主要介紹了如何修改json字符串中某個(gè)key對(duì)應(yīng)的value值操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Java集合中的TreeMap解讀

    Java集合中的TreeMap解讀

    這篇文章主要介紹了Java集合中的TreeMap解讀,TreeMap可以傳入一個(gè)實(shí)現(xiàn)了 Comparator接口的一個(gè)匿名內(nèi)部類,匿名內(nèi)部類里面我們?nèi)匀豢梢匀ブ付ㄌ砑游覀兊逆I值對(duì)的這種排序規(guī)則,需要的朋友可以參考下
    2023-09-09
  • 詳解Java如何應(yīng)對(duì)常見的安全威脅和攻擊類型

    詳解Java如何應(yīng)對(duì)常見的安全威脅和攻擊類型

    隨著信息技術(shù)的快速發(fā)展,網(wǎng)絡(luò)安全問題日益突出,本文將以Java開發(fā)語言為例,深入探討網(wǎng)絡(luò)協(xié)議的安全性問題,通過分析常見的安全威脅和攻擊類型,設(shè)計(jì)和實(shí)施安全協(xié)議等主題,為讀者提供一些有益的思路和方法,需要的朋友可以參考下
    2023-11-11
  • Java運(yùn)算符>、>>、>>>三者的區(qū)別

    Java運(yùn)算符>、>>、>>>三者的區(qū)別

    這篇文章主要介紹了Java運(yùn)算符>、>>、>>>三者的區(qū)別,做了一個(gè)簡單的對(duì)比,并用實(shí)例說明,需要的朋友可以參考下
    2014-06-06
  • Idea設(shè)置全局highlighting?level為Syntax問題

    Idea設(shè)置全局highlighting?level為Syntax問題

    這篇文章主要介紹了Idea設(shè)置全局highlighting?level為Syntax問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04

最新評(píng)論