![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5CZmlDMwQTM5IGNjRzY0UGN5ETMhVTMmhDOmNGNxUGM08CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
JWT(JSON WEB TOKEN)是基于RFC 7519标準定義的一種可以安全傳輸的小巧和自包含的JSON對象。由于資料是使用數字簽名的,是以是可信任的和安全的。JWT可以使用HMAC算法對secret進行加密或者使用RSA的公鑰私鑰對來進行簽名。
JWT通常由頭部(Header),負載(Payload),簽名(Signature)三個部分組成,中間以.号分隔,其格式為Header.Payload.Signature
Header:聲明令牌的類型和使用的算法
alg:簽名的算法
typ:token的類型,比如JWT
Payload:也稱為JWT Claims,包含使用者的一些資訊
系統保留的聲明(Reserved claims):
iss (issuer):簽發人
exp (expiration time):過期時間
sub (subject):主題
aud (audience):閱聽人使用者
nbf (Not Before):在此之前不可用
iat (Issued At):簽發時間
jti (JWT ID):JWT唯一辨別,能用于防止JWT重複使用
公共的聲明(public):
見 http://www.iana.org/assignments/jwt/jwt.xhtml
私有的聲明(private claims):
根據業務需要自己定義的資料
Signature:簽名
簽名格式:
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
JWT的特點:
- JWT預設是不加密的,不能把使用者敏感類資訊放在Payload部分。
- JWT 不僅可以用于認證,也可以用于交換資訊。
- JWT的最大缺點是伺服器不儲存會話狀态,是以在使用期間不可能取消令牌或更改令牌的權限。
- JWT本身包含認證資訊,為了減少盜用,JWT的有效期不宜設定太長。
- 為了減少盜用和竊取,JWT不建議使用HTTP協定來傳輸代碼,而是使用加密的HTTPS協定進行傳輸。
首次生成token比較慢,比較耗CPU,在高并發的情況下需要考慮CPU占用問題。
生成的token比較長,可能需要考慮流量問題。
認證原理:
用戶端向伺服器申請授權,伺服器認證以後,生成一個token字元串并傳回給用戶端,此後用戶端在請求受保護的資源時攜帶這個token,服務端進行驗證再從這個token中解析出使用者的身份資訊。
JWT的使用方式:
一種做法是放在HTTP請求的頭資訊Authorization字段裡面,格式如下:
Authorization:
需要将伺服器設定為接受來自所有域的請求,用Access-Control-Allow-Origin: *
另一種做法是,跨域的時候,JWT就放在POST請求的資料體裡面。
對JWT實作token續簽的做法:
1、額外生成一個refreshToken用于擷取新token,refreshToken需存儲于服務端,其過期時間比JWT的過期時間要稍長。
2、使用者攜帶refreshToken參數請求token重新整理接口,服務端在判斷refreshToken未過期後,取出關聯的使用者資訊和目前token。
3、使用目前使用者資訊重新生成token,并将舊的token置于黑名單中,傳回新的token。
建立用于登入認證的工程auth-service:
1、 建立pom.xml檔案
Xml代碼
4.0.0com.seasy.springcloud auth-service 1.0.0jarorg.springframework.boot spring-boot-starter-parent 2.0.8.RELEASE1.8UTF-8UTF-8org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-actuator org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.boot spring-boot-starter-data-redis org.apache.commons commons-pool2 com.auth0 java-jwt 3.7.0org.springframework.cloud spring-cloud-dependencies Finchley.RELEASEpomimport
2、JWT工具類
Java代碼
public class JWTUtil { public static final String SECRET_KEY = "123456"; //秘鑰 public static final long TOKEN_EXPIRE_TIME = 5 * 60 * 1000; //token過期時間 public static final long REFRESH_TOKEN_EXPIRE_TIME = 10 * 60 * 1000; //refreshToken過期時間 private static final String ISSUER = "issuer"; //簽發人 /** * 生成簽名 */ public static String generateToken(String username){ Date now = new Date(); Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY); //算法 String token = JWT.create() .withIssuer(ISSUER) //簽發人 .withIssuedAt(now) //簽發時間 .withExpiresAt(new Date(now.getTime() + TOKEN_EXPIRE_TIME)) //過期時間 .withClaim("username