主要代碼
1 //JWT 默認過期時間,3600L,單位秒 2 Long expireSecond = 3600L; 3 //鹽值 4 String newSalt = 666; 5 String token = JwtUtil.generateToken(user.getUsername(), newSalt, 6 Duration.ofSeconds(expireSecond));
JwtUtil.generateToken方法
1 /** 2 * 生成JWT Token 3 * 4 * @param username 用戶名 5 * @param salt 鹽值 6 * @param expireDuration 過期時間和單位 7 * @return token 8 */ 9 public static String generateToken(String username, String salt, Duration expireDuration) { 10 try { 11 if (StringUtils.isBlank(username)) { 12 log.error("username不能為空"); 13 return null; 14 } 15 log.debug("username:{}", username); 16 17 // 如果鹽值為空,則使用默認值:666666 18 if (StringUtils.isBlank(salt)) { 19 salt = "666666; 20 } 21 22 // 過期時間,單位:秒 23 Long expireSecond; 24 // 默認過期時間為1小時 3600L 單位秒 25 if (expireDuration == null) { 26 expireSecond = "3600L"; 27 } else { 28 expireSecond = expireDuration.getSeconds(); 29 } 30 Date expireDate = DateUtils.addSeconds(new Date(), expireSecond.intValue()); 31 32 // 生成token 33 Algorithm algorithm = Algorithm.HMAC256(salt); 34 String token = JWT.create() 35 .withClaim(CommonConstant.JWT_USERNAME, username) 36 // jwt唯一id 37 .withJWTId(UUIDUtil.getUuid()) 38 // 簽發人 39 .withIssuer("") 40 // 主題 41 .withSubject("") 42 // 簽發的目標 43 .withAudience("") 44 // 簽名時間 45 .withIssuedAt(new Date()) 46 // token過期時間 47 .withExpiresAt(expireDate) 48 // 簽名 49 .sign(algorithm); 50 return token; 51 } catch (Exception e) { 52 log.error("generateToken exception", e); 53 } 54 return null; 55 }
一些概念
JSON Web Token(JWT),是目前最流行的跨域認證解決方案。
JWT的原理
服務器認證以后,生成一個JSON格式的對象返回給客戶端。之后客戶端與服務端通信的時候,都要發回這個JSON對象。服務器完全根據這個對象認證用戶身份。
JWT的組成
JWT 由三部分組成,它們之間圓點(.)連接。這個三部分分別是:
Header
Payload
Signature
一個典型的JWT看起來是這個樣子的: xxxxx.yyyyy.zzzzz
Header
header典型的由兩部分組成:token的類型比如JWT、算法名稱比如HMAC SHA256。
Payload
載荷,它包含聲明(要求)。聲明是關於實體和其他數據的聲明。聲明有三種類型:registered、public和private。
- Registered claims : 這里有一組預定義的聲明,它們不是強制的,但是推薦。比如:iss (issuer), exp (expiration time), sub (subject), aud (audience)等。
- Public claims : 可以隨意定義。
- Private claims : 用於在同意使用它們的各方之間共享信息,並且不是注冊的或公開的聲明。
{ "iss": "Online JWT Builder", "iat": 1416797419, "exp": 1448333419, "aud": "www.example.com", "sub": "jrocket@example.com", "GivenName": "Johnny", "Surname": "Rocket", "Email": "jrocket@example.com", "Role": [ "Manager", "Project Administrator" ] }
iss: 該JWT的簽發者,是否使用是可選的;
sub: 該JWT所面向的用戶,是否使用是可選的;
aud: 接收該JWT的一方,是否使用是可選的;
exp(expires): 什么時候過期,這里是一個Unix時間戳,是否使用是可選的;
iat(issued at): 在什么時候簽發的(UNIX時間),是否使用是可選的;
其他還有:nbf (Not Before):如果當前時間在nbf里的時間之前,則Token不被接受;一般都會留一些余地,比如幾分鍾,是否使用是可選的
將上面的JSON對象進行[base64編碼]可以得到下面的字符串。這個字符串我們將它稱作JWT的Payload(載荷)。
eyJpc3MiOiJKb2huIFd1IEpXVCIsImlhdCI6MTQ0MTU5MzUwMiwiZXhwIjoxNDQxNTk0NzIyLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJqcm9ja2V0QGV4YW1wbGUuY29tIiwiZnJvbV91c2VyIjoiQiIsInRhcmdldF91c2VyIjoiQSJ9
注意,不要在JWT的payload或header中放置敏感信息,除非它們是加密的。
Signature
將上面Header、Payload編碼后的字符串都用.依次連接起來后用一個密鑰,就形成了簽名。
具體如下圖所示:
可學習的相關博客(學習更深的知識)