您好,登錄后才能下訂單哦!
今天小編給大家分享一下Java JWT如何實現跨域身份驗證的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
JWT(JSON Web Token)是目前流行的跨域認證解決方案,是一個開放標準(RFC 7519),它定義了一種緊湊的、自包含的方式,用于作為JSON對象在各方之間安全地傳輸信息。該信息可以被驗證和信任,因為它是數字簽名的。
JWT是由頭部(header)、載荷(payload)、簽證(signature)三段信息構成的,將三段信息文本用"."連接在一起就構成了JWT字符串。
例如:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
使用在線校驗工具(https://jwt.io/)將上述Token進行解碼就可以看到數據,如下圖所示
JWT的頭部承載兩部分信息:
(1)聲明類型:這里主要是JWT。
(2)聲明加密算法:通常直接使用HMAC SHA256。
例如:
{ "alg": "HS256", "typ": "JWT" }
alg屬性表示簽名所使用的算法;
JWT簽名默認的算法為HMAC SHA256;
alg屬性值HS256就是HMAC SHA256算法;
type屬性表示令牌類型,這里是JWT。
載荷是JWT的主體,同樣也是一個JSON對象。載荷包含三個部分:
(1)標準中的聲明(Registered Claims):一組預定義的聲明,不是強制的,但是推薦。
iss(issuer):JWT簽發者
sub(subject):JWT索所面向的用戶
aud(audience):接收JWT的一方
exp(expiration):JWT的過期時間,必須要大于簽發時間。
nbf(not before):定義了再什么時間之前該JWT都是不可用的。
iat(issued at):JWT的發布時間,UNIX時間戳。
jti(JWT ID):JWT的唯一ID編號。
(2)公共的聲明:可以添加任意信息,一般添加用戶的相關信息或其他業務需要的必要信息,但不建議添加敏感信息。
(3)私有的聲明:提供者和消費者所共同定義的聲明,一般不建議存放敏感信息。
JWT的第三部分是一個簽證信息,由三部分組成:header(base64后的)、payload(base64后的)、secret(密鑰,需要保存好)。
例如:
HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)
簽名用于驗證消息再傳遞過程中有沒有被更改,并且對于使用私鑰簽名的Token還可以驗證JWT的發送方是否為它所說的發送方。
secret是保存在服務端的,JWT的簽發生成也是在服務端的,secret就是用來進行JWT的簽發和驗證的,所以secret是服務端的私鑰,在任何場景都不應該流露出去。
JWT的原則是在服務器身份驗證之后,將生成一個JSON對象并將其發送回用戶,如下所示。
{ "sub": "1234567890", "name": "Helen", "admin": true }
之后,當用戶與服務器通信時,客戶在請求中發回JSON對象。服務器僅依賴于這個JSON對象來標識用戶。為了防止用戶篡改數據,服務器將在生成對象時添加簽名。
服務器不保存任何會話數據,即服務器變為無狀態,使其更容易擴展。
客戶端接收服務器返回的JWT,將其存儲在Cookie或localStorage中。
此后,客戶端將在與服務器交互中都會帶JWT。如果將它存儲在Cookie中,就可以自動發送,但是不會跨域,因此一般是將它放入HTTP請求的Header Authorization字段中。當跨域時,也可以將JWT被放置于POST請求的數據主體中。
JWT不僅可用于認證,還可用于信息交換。善用JWT有助于減少服務器請求數據庫的次數。
生產的token可以包含基本信息,比如id、用戶昵稱、頭像等信息,避免再次查庫
存儲在客戶端,不占用服務端的內存資源
JWT默認不加密,但可以加密。生成原始令牌后,可以再次對其進行加密。
當JWT未加密時,一些私密數據無法通過JWT傳輸。
JWT的最大缺點是服務器不保存會話狀態,所以在使用期間不可能取消令牌或更改令牌的權限。也就是說,一旦JWT簽發,在有效期內將會一直有效。
JWT本身包含認證信息,token是經過base64編碼,所以可以解碼,因此token加密前的對象不應該包含敏感信息,一旦信息泄露,任何人都可以獲得令牌的所有權限。為了減少盜用,JWT的有效期不宜設置太長。對于某些重要操作,用戶在使用時應該每次都進行進行身份驗證。
為了減少盜用和竊取,JWT不建議使用HTTP協議來傳輸代碼,而是使用加密的HTTPS協議進行傳輸。
<dependencies> <!-- JWT--> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> </dependency> </dependencies>
/** * JWT工具類 */ public class JwtHelper { //過期時間 private static long tokenExpiration = 24*60*60*1000; //token簽名密鑰 private static String tokenSignKey = "123456"; //根據參數生成token public static String createToken(Long userId, String userName) { String token = Jwts.builder() .setSubject("YYGH-USER") //設置過期時間 30分鐘 .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration)) //設置主題信息 用戶id和用戶名稱 .claim("userId", userId) .claim("userName", userName) //簽名哈希 .signWith(SignatureAlgorithm.HS512, tokenSignKey) .compressWith(CompressionCodecs.GZIP) .compact(); return token; } //根據token字符串得到用戶id public static Long getUserId(String token) { if(StringUtils.isEmpty(token)) return null; Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token); Claims claims = claimsJws.getBody(); Integer userId = (Integer)claims.get("userId"); return userId.longValue(); } //根據token字符串得到用戶名稱 public static String getUserName(String token) { if(StringUtils.isEmpty(token)) return ""; Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token); Claims claims = claimsJws.getBody(); return (String)claims.get("userName"); } }
寫個主函數測試下:
public static void main(String[] args) { String token = JwtHelper.createToken(1L, "lucy"); System.out.println(token); System.out.println(JwtHelper.getUserId(token)); System.out.println(JwtHelper.getUserName(token)); }
簽發和解析都沒問題。
以上就是“Java JWT如何實現跨域身份驗證”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。