1、JWT
JWT是JSON WEB TOKEN的缩写,它是基于 RFC 7519标准定义的一种可以安全传输的的JSON对象,由于使用了数字签名,所以是可信任和安全的。
1.JWT的组成
- JWT token的格式:header.payload.signature
- header中用于存放签名的生成算法
{"alg": "HS512"}
- payload中用于存放用户名、token的生成时间和过期时间
{"sub":"admin","created":1489079981393,"exp":1489684781}
- signature为以header和payload生成的签名,一旦header和payload被篡改,验证将失败
//secret为加密算法的密钥 String signature = HMACSHA512(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)
2.JWT实现认证和授权的原理
- 用户调用登录接口,登录成功后获取到JWT的token;
- 之后用户每次调用接口都在http的header中添加一个叫Authorization的头,值为JWT的token;
- 后台程序通过对Authorization头中信息的解码及数字签名校验来获取其中的用户信息,从而实现认证和授权。
2、SpringBoot + Shiro + JWT 实现认证和授权
- 项目结构
2. 开发环境及导入相关maven依赖
- IDEA:2018.2(lombok插件)
- SpringBoot:2.3.1.RELEASE
- Shiro:1.4.1
- JWT:3.2.0
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
- 集成JWT
- JwtUti
利用 JWT 的工具类来生成token。这个工具类有生成 token 和 校验 token 以及从token中获取信息
@Slf4j
public class JwtUtil {
private static final Long EXPIRE_TIME = 5 * 60 * 1000L;
private static final String SECRET = "SHIRO+JWT";
/**
* 生成 token 时,指定 token 过期时间 EXPIRE_TIME 和签名密钥 SECRET,
* 然后将 expireDate 和 username 写入 token 中,并使用带有密钥的 HS256 签名算法进行签名
* @param username
* @return
*/
public static String createToken(String username) {
String token = null;
try {
// 过期时间
Date expireDate = new Date(System.currentTimeMillis() + EXPIRE_TIME);
// 加密算法
Algorithm algorithm = Algorithm.HMAC256(SECRET);
token = JWT.create()
.withClaim("username", username)
.withExpiresAt(expireDate)
.sign(algorithm);
} catch (UnsupportedEncodingException e) {
log.error("Failed to create token. {}", e.getMessage());
}
return token;
}
/**
* 验证token,如果验证失败,便会抛出异常
* @param token
* @param username
* @return
*/
public static boolean verify(String token, String username) {
boolean isSuccess = false;
try {
Algorithm algorithm = Algorithm.HMAC256(SECRET);
JWTVerifier verifier = JWT.require(algorithm)
.withClaim("username", username)
.build