這篇文章將為大家詳細講解有關(guān)如何分析并實踐JSON WEB TOKEN,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。
網(wǎng)站設(shè)計制作、成都網(wǎng)站建設(shè)的開發(fā),更需要了解用戶,從用戶角度來建設(shè)網(wǎng)站,獲得較好的用戶體驗。創(chuàng)新互聯(lián)多年互聯(lián)網(wǎng)經(jīng)驗,見的多,溝通容易、能幫助客戶提出的運營建議。作為成都一家網(wǎng)絡(luò)公司,打造的就是網(wǎng)站建設(shè)產(chǎn)品直銷的概念。選擇創(chuàng)新互聯(lián),不只是建站,我們把建站作為產(chǎn)品,不斷的更新、完善,讓每位來訪用戶感受到浩方產(chǎn)品的價值服務(wù)。JSON Web Token(JWT)是一個非常輕巧的規(guī)范。
這個規(guī)范允許我們使用JWT在用戶和服務(wù)器之間傳遞安全可靠的信息。 簡稱JWT,在HTTP通信過程中,進行身份認證。
我們知道HTTP通信是無狀態(tài)的,因此客戶端的請求到了服務(wù)端處理完之后是無法返回給原來的客戶端。
因此需要對訪問的客戶端進行識別,常用的做法是通過session機制:
客戶端在服務(wù)端登陸成功之后,服務(wù)端會生成一個sessionID,返回給客戶端,客戶端將sessionID保存到cookie中,再次發(fā)起請求的時候,攜帶cookie中的sessionID到服務(wù)端,服務(wù)端會緩存該session(會話),當客戶端請求到來的時候,服務(wù)端就知道是哪個用戶的請求,并將處理的結(jié)果返回給客戶端,完成通信。
通過上面的分析,可以知道session存在以下問題:
1、session保存在服務(wù)端,當客戶訪問量增加時,服務(wù)端就需要存儲大量的session會話,對服務(wù)器有很大的考驗;
2、當服務(wù)端為集群時,用戶登陸其中一臺服務(wù)器,會將session保存到該服務(wù)器的內(nèi)存中,但是當用戶的訪問到其他服務(wù)器時,會無法訪問,通常采用緩存一致性技術(shù)來保證可以共享,或者采用第三方緩存來保存session,不方便。
客戶端通過用戶名和密碼登錄服務(wù)器;
服務(wù)端對客戶端身份進行驗證;
服務(wù)端對該用戶生成Token,返回給客戶端;
客戶端發(fā)起請求,需要攜帶該Token;
服務(wù)端收到請求后,首先驗證Token,之后返回數(shù)據(jù)。
客戶端將Token保存到本地瀏覽器,一般保存到cookie中。
服務(wù)端不需要保存Token,只需要對Token中攜帶的信息進行驗證即可;
無論客戶端訪問后臺的那臺服務(wù)器,只要可以通過用戶信息的驗證即可。
JWT 的原理是,服務(wù)器認證以后,生成一個 JSON 對象,發(fā)回給用戶,就像下面這樣。
{ "姓名": "張三", "角色": "管理員", "到期時間": "2018年10月31日0點0分"}
以后,用戶與服務(wù)端通信的時候,都要發(fā)回這個 JSON 對象。服務(wù)器完全只靠這個對象認定用戶身份。為了防止用戶篡改數(shù)據(jù),服務(wù)器在生成這個對象的時候,會加上簽名(詳見后文)。
服務(wù)器就不保存任何 session 數(shù)據(jù)了,也就是說,服務(wù)器變成無狀態(tài)了,從而比較容易實現(xiàn)擴展。
實際的 JWT 大概就像下面這樣。
它是一個很長的字符串,中間用點(.
)分隔成三個部分。注意,JWT 內(nèi)部是沒有換行的,這里只是為了便于展示,將它寫成了幾行。
JWT 的三個部分依次如下。
Header(頭部)
Payload(負載)
Signature(簽名)
寫成一行,就是下面的樣子。
Header 部分是一個 JSON 對象,描述 JWT 的元數(shù)據(jù),通常是下面的樣子。
{ "alg": "HS256", "typ": "JWT"}
上面代碼中,alg屬性表示簽名的算法(algorithm),默認是 HMAC SHA256(寫成 HS256);typ屬性表示這個令牌(token)的類型(type),JWT 令牌固定寫為JWT。
最后,將上面的 JSON 對象使用 Base64URL 算法(詳見后文)轉(zhuǎn)成字符串。
Payload 部分也是一個 JSON 對象,用來存放實際需要傳遞的數(shù)據(jù)。JWT 規(guī)定了7個官方字段,供選用。
iss (issuer):簽發(fā)人
exp (expiration time):過期時間
sub (subject):主題
aud (audience):受眾
nbf (Not Before):生效時間
iat (Issued At):簽發(fā)時間
jti (JWT ID):編號
除了官方字段,你還可以在這個部分定義私有字段,下面就是一個例子。
{ "sub": "1234567890", "name": "John Doe", "admin": true}
注意,JWT 默認是不加密的,任何人都可以讀到,所以不要把秘密信息放在這個部分。
這個 JSON 對象也要使用 Base64URL 算法轉(zhuǎn)成字符串。
Signature 部分是對前兩部分的簽名,防止數(shù)據(jù)篡改。
首先,需要指定一個密鑰(secret)。這個密鑰只有服務(wù)器才知道,不能泄露給用戶。然后,使用 Header 里面指定的簽名算法(默認是 HMAC SHA256),按照下面的公式產(chǎn)生簽名。
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
算出簽名以后,把 Header、Payload、Signature 三個部分拼成一個字符串,每個部分之間用"點"(.
)分隔,就可以返回給用戶。
前面提到,Header 和 Payload 串型化的算法是 Base64URL。這個算法跟 Base64 算法基本類似,但有一些小的不同。
JWT 作為一個令牌(token),有些場合可能會放到 URL(比如 api.example.com/?token=xxx)。
Base64 有三個字符+、/
和=
,在 URL 里面有特殊含義,所以要被替換掉:=
被省略、+
替換成-
,/
替換成_
。這就是 Base64URL 算法。
客戶端收到服務(wù)器返回的 JWT,可以儲存在 Cookie 里面,也可以儲存在 localStorage。
此后,客戶端每次與服務(wù)器通信,都要帶上這個 JWT。你可以把它放在 Cookie 里面自動發(fā)送,但是這樣不能跨域,所以更好的做法是放在 HTTP 請求的頭信息Authorization
字段里面。
Authorization: Bearer <token>
另一種做法是,跨域的時候,JWT 就放在 POST 請求的數(shù)據(jù)體里面。
JWT 默認是不加密,但也是可以加密的。生成原始 Token 以后,可以用密鑰再加密一次。
JWT 不加密的情況下,不能將秘密數(shù)據(jù)寫入 JWT。
JWT 不僅可以用于認證,也可以用于交換信息。有效使用 JWT,可以降低服務(wù)器查詢數(shù)據(jù)庫的次數(shù)。
JWT 的大缺點是,由于服務(wù)器不保存 session 狀態(tài),因此無法在使用過程中廢止某個 token,或者更改 token 的權(quán)限。也就是說,一旦 JWT 簽發(fā)了,在到期之前就會始終有效,除非服務(wù)器部署額外的邏輯。
JWT 本身包含了認證信息,一旦泄露,任何人都可以獲得該令牌的所有權(quán)限。為了減少盜用,JWT 的有效期應(yīng)該設(shè)置得比較短。對于一些比較重要的權(quán)限,使用時應(yīng)該再次對用戶進行認證。
為了減少盜用,JWT 不應(yīng)該使用 HTTP 協(xié)議明碼傳輸,要使用 HTTPS 協(xié)議傳輸。
創(chuàng)建一個maven項目,加入pom依賴:
<!--JWT--><dependencies><!--JWT--> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>RELEASE</version> <scope>compile</scope> </dependency></dependencies><build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.5</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins></build>
創(chuàng)建類JWTDemo:
public class JWTDemo { //加密的 private static final String SECRET_KEY = "123456789"; @Test public void jwtTest() throws InterruptedException { // 設(shè)置3秒后過期 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); long time = System.currentTimeMillis() + 30*60*1000; String jwt = this.buildJwt(new Date(time)); System.out.println("jwt = " + jwt); // 驗證token是否可用 boolean isOk = this.isJwtValid(jwt); System.out.println(isOk); } public String buildJwt(Date exp) { String jwt = Jwts.builder() .signWith(SignatureAlgorithm.HS256, SECRET_KEY) //SECRET_KEY是加密算法對應(yīng)的密鑰,這里使用額是HS256加密算法 .setExpiration(exp) //expTime是過期時間 .claim("name","wangtingjun") .claim("age","18") .claim("key", "vaule") //該方法是在JWT中加入值為vaule的key字段 .compact(); return jwt; } public boolean isJwtValid(String jwt) { try { //解析JWT字符串中的數(shù)據(jù),并進行最基礎(chǔ)的驗證 Claims claims = Jwts.parser() .setSigningKey(SECRET_KEY) //SECRET_KEY是加密算法對應(yīng)的密鑰,jjwt可以自動判斷機密算法 .parseClaimsJws(jwt) //jwt是JWT字符串 .getBody(); System.out.println(claims); String vaule = claims.get("key", String.class); //獲取自定義字段key //判斷自定義字段是否正確 if ("vaule".equals(vaule)) { return true; } else { return false; } } //在解析JWT字符串時,如果密鑰不正確,將會解析失敗,拋出SignatureException異常,說明該JWT字符串是偽造的 //在解析JWT字符串時,如果‘過期時間字段’已經(jīng)早于當前時間,將會拋出ExpiredJwtException異常,說明本次請求已經(jīng)失效 catch (SignatureException | ExpiredJwtException e) { return false; } }}
最后可以在控制臺看到打印出來的信息
jwt = eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NDA5NzgxMzAsIm5hbWUiOiJ3YW5ndGluZ2p1biIsImFnZSI6IjE4Iiwia2V5IjoidmF1bGUifQ.XEDlK0UNTV3aKANQe9QCE2Y7JiP7D7ebrDVOs2JxRCQ{exp=1540978130, name=wangtingjun, age=18, key=vaule}true
關(guān)于如何分析并實踐JSON WEB TOKEN就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
當前題目:如何分析并實踐JSONWEBTOKEN-創(chuàng)新互聯(lián)
標題路徑:http://jinyejixie.com/article22/djeejc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營銷、自適應(yīng)網(wǎng)站、App設(shè)計、用戶體驗、標簽優(yōu)化、全網(wǎng)營銷推廣
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容