JWT介绍和使用
提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔
文章目錄
- 前言
- 一、JWT是什么?
- 二、為什么選擇JWT
- 1.支持跨域訪問
- 2.無狀態
- 3.更適用于移動端
- 三、JWT使用
- 1.工具類
- 2.使用
- 總結
前言
本文介紹了JWT的基本概念,優點和使用方法,并提供了簡單的jwtToken的工具類以便快速上手使用
提示:以下是本篇文章正文內容,下面案例可供參考
一、JWT是什么?
JWT是英文JSON Web Token的縮寫,看到token我們的第一印象他是認證用的。
通俗地說,JWT的本質就是一個不規則字符串,它可以將用戶相關信息保存到一個Json字符串中,然后進行編碼后得到一個JWT token,并且這個JWT token帶有簽名信息,接收后可以校驗是否被篡改。
二、為什么選擇JWT
1.支持跨域訪問
cookie是無法跨域的,而token由于沒有用到cookie(前提是將token放到請求頭中),所以跨域后不會存在信息丟失問題
2.無狀態
token機制在服務端不需要存儲session信息,因為token自身包含了所有登錄用戶的信息,所以可以減輕服務端壓力
3.更適用于移動端
當客戶端是非瀏覽器平臺時,cookie是不被支持的,此時采用token認證方式會簡單很多
三、JWT使用
1.工具類
代碼如下:
/*** <p>jwt token工具類</p>* <pre>* jwt的claim里一般包含以下幾種數據:* 1. iss -- token的發行者* 2. sub -- 該JWT所面向的用戶* 3. aud -- 接收該JWT的一方* 4. exp -- token的失效時間* 5. nbf -- 在此時間段之前,不會被處理* 6. iat -- jwt發布時間* 7. jti -- jwt唯一標識,防止重復使用* </pre>*/ public class JwtTokenUtil {/*** 獲取用戶名從token中*/public static String getUsernameFromToken(String token) {return getClaimFromToken(token).getSubject();}/*** 獲取jwt發布時間*/public static Date getIssuedAtDateFromToken(String token) {return getClaimFromToken(token).getIssuedAt();}/*** 獲取jwt失效時間*/public static Date getExpirationDateFromToken(String token) {return getClaimFromToken(token).getExpiration();}/*** 獲取jwt接收者*/public static String getAudienceFromToken(String token) {return getClaimFromToken(token).getAudience();}/*** 獲取私有的jwt claim*/public static String getPrivateClaimFromToken(String token, String key) {return getClaimFromToken(token).get(key).toString();}/*** 獲取jwt的payload部分*/public static Claims getClaimFromToken(String token) {return Jwts.parser().setSigningKey(JwtConstants.SECRET).parseClaimsJws(token).getBody();}/*** 解析token是否正確,不正確會報異常<br>*/public static void parseToken(String token) throws JwtException {Jwts.parser().setSigningKey(JwtConstants.SECRET).parseClaimsJws(token).getBody();}/*** <pre>* 驗證token是否失效* true:過期 false:沒過期* </pre>*/public static Boolean isTokenExpired(String token) {try {Date expiration = getExpirationDateFromToken(token);return expiration.before(new Date());} catch (ExpiredJwtException expiredJwtException) {return true;}}/*** 生成token(通過用戶名和簽名時候用的隨機數)*/public static String generateToken(String userId) {Map<String, Object> claims = new HashMap<>();return doGenerateToken(claims, userId);}/*** 生成token(通過用戶名和簽名時候用的隨機數) 可存額外字段 claims*/public static String generateToken(Map<String, Object> claims, String userId) {return doGenerateToken(claims, userId);}/*** 生成token*/private static String doGenerateToken(Map<String, Object> claims, String subject) {Date createdDate = new Date();Date expirationDate = new Date(createdDate.getTime() + JwtConstants.EXPIRATION * 1000);return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(createdDate).setExpiration(expirationDate).signWith(SignatureAlgorithm.HS512, JwtConstants.SECRET).compact();}/*** 獲取混淆MD5簽名用的隨機字符串*/public static String getRandomKey() {return getRandomString(6);}/*** 獲取隨機字符,自定義長度** @author soofuju* @Date 2018/3/18 21:55*/public static String getRandomString(int length) {String base = "abcdefghijklmnopqrstuvwxyz0123456789";Random random = new Random();StringBuffer sb = new StringBuffer();for (int i = 0; i < length; i++) {int number = random.nextInt(base.length());sb.append(base.charAt(number));}return sb.toString();} }2.使用
代碼如下:
public static void main(String[] args) {Map<String, Object> claims = new HashMap<>();claims.put("info", new UserTerminalAuthDO().setNickName("張三").setMobile("13811111111"));//生成JWTtokenString token = JwtTokenUtil.generateToken(claims, "1");//獲取token存儲的userIdString usernameFromToken = JwtTokenUtil.getUsernameFromToken(token);//獲取token存儲的claimsClaims claimFromToken = JwtTokenUtil.getClaimFromToken(token);}總結
JWT的確有他自己的優勢,但是任何的方法都存在它的局限性,JWT也不例外:Jwt生成之后無法修改(發生變化)、而且JWT的token長度與其包含用戶信息多少正相關,傳輸開銷較大、無法吊銷令牌,只能等待令牌自身過期。所以還是需要根據具體的開發需求選擇適合的方法進行開發。
總結
- 上一篇: TIE论文投递
- 下一篇: 上位机与MES对接的常见方式