JWT(Json web token)是一個開放標準(RFC 7519),用來在各方之間安全地傳輸信息。JWT攜帶數字簽名,是能夠被驗證和信任的官方地址java
組成 | 做用 | 內容 |
---|---|---|
Header(頭) | 記錄令牌類型,簽名算法等 | {"alg":"HS256","typ":"JWT"} |
Payload(有效載荷) | 攜帶用戶信息 | {"id":"1"} |
Signature(簽名) | 簽名防篡改 |
Token=Base64(Header).Base64(Payload).Base64(Signature) Signature=Header定義算法(Base64(Header).Base64(Payload),secret)git
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<scope>runtime</scope>
</dependency>
複製代碼
無
複製代碼
無
複製代碼
package com.virgo.auth;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import javax.crypto.SecretKey;
import java.util.Date;
import java.util.Map;
/**
* @author zhaozha
* @date 2019/10/24 下午2:48
*/
@Slf4j
@Data
@Builder
@RequiredArgsConstructor
@AllArgsConstructor
public class JwtOperator {
private String secret;
private Long expirationTimeInSecond;
/**
* 從token中獲取claim
*
* @param token token
* @return claim
*/
public Claims getClaimsFromToken(String token) {
try {
return Jwts.parser()
.setSigningKey(this.secret.getBytes())
.parseClaimsJws(token)
.getBody();
} catch (ExpiredJwtException | UnsupportedJwtException | MalformedJwtException | IllegalArgumentException e) {
log.error("token解析錯誤", e);
throw new IllegalArgumentException("Token invalided.");
}
}
/**
* 獲取token的過時時間
*
* @param token token
* @return 過時時間
*/
public Date getExpirationDateFromToken(String token) {
return getClaimsFromToken(token)
.getExpiration();
}
/**
* 判斷token是否過時
*
* @param token token
* @return 已過時返回true,未過時返回false
*/
private Boolean isTokenExpired(String token) {
Date expiration = getExpirationDateFromToken(token);
return expiration.before(new Date());
}
/**
* 計算token的過時時間
*
* @return 過時時間
*/
private Date getExpirationTime() {
return new Date(System.currentTimeMillis() + this.expirationTimeInSecond * 1000);
}
/**
* 爲指定用戶生成token
*
* @param claims 用戶信息
* @return token
*/
public String generateToken(Map<String, Object> claims) {
Date createdTime = new Date();
Date expirationTime = this.getExpirationTime();
byte[] keyBytes = secret.getBytes();
SecretKey key = Keys.hmacShaKeyFor(keyBytes);
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(createdTime)
.setExpiration(expirationTime)
// 你也能夠改用你喜歡的算法
// 支持的算法詳見:https://github.com/jwtk/jjwt#features
.signWith(key, SignatureAlgorithm.HS256)
.compact();
}
/**
* 判斷token是否非法
*
* @param token token
* @return 未過時返回true,不然返回false
*/
public Boolean validateToken(String token) {
return !isTokenExpired(token);
}
}
package com.virgo.user.configuration;
import com.virgo.auth.JwtOperator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author zhaozha
* @date 2019/10/24 下午3:22
*/
@Configuration
public class JwtOperatorConfiguration {
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expire-time-in-second}")
private Long expirationTimeInSecond;
@Bean
public JwtOperator jwtOperator(){return new JwtOperator(secret,expirationTimeInSecond);}
}
複製代碼
jwt:
secret: virgo
# 有效期,單位秒,默認2周
expire-time-in-second: 1209600
複製代碼