在 Spring Boot 中 采用 JWt 的认证方案,可以是自己实现的,也可以是现有三方库调用,今天主要从 jjwt 这个三方库学习下怎么应用在 Spring Boot 中。
环境:
- Spring Boot:3.1.16
- JDK:17
依赖:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.12.3</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.12.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred -->
<version>0.12.3</version>
<scope>runtime</scope>
</dependency>
jwt工具类
我们将 生成token 和 解析验证token 放在工具类中:
package com.example.springbootauthdemo.util;
import io.jsonwebtoken.*;
import javax.crypto.SecretKey;
import java.util.Date;
public class JJWTUsage {
private static final SecretKey key = Jwts.SIG.HS256.key().build();
public static String createTokenV1(String username) {
JwtBuilder builder = Jwts.builder(); // 隐式创建了实例,如果Jwts.header()...builder()则显示
// set header
builder.header().keyId("aKeyId").and();
// set payload
builder.subject(username).expiration(new Date(System.currentTimeMillis() + 3600 * 1000));
// signature
builder.signWith(key);
// compact to generate jwt
return builder.compact();
}
public static boolean parseTokenV1(String token) {
try {
// create JwtParseBuilder instance
JwtParserBuilder builder = Jwts.parser();
// parse token
builder.verifyWith(key);
// create thread-safe JwtParser
JwtParser jwtParser = builder.build();
// parse token in react
Jws<Claims> jws = jwtParser.parseSignedClaims(token);
// get payload and the added filed value
Date expiration = jws.getPayload().getExpiration();
// verify expire or not
if (expiration.before(new Date())) {
return false;
}
return true;
} catch (JwtException|IllegalArgumentException e) {
e.printStackTrace();
}
return false;
}
}
控制器类-认证
package com.example.springbootauthdemo.controller;
import com.example.springbootauthdemo.param.User;
import com.example.springbootauthdemo.util.JJWTUsage;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LoginV1Controller {
@PostMapping("/loginV1")
public Object login(@RequestBody User user) {
// 第一次登陆,通常会通过拦截件先过滤下请求
String token;
if (user.getUsername().equals("admin") && user.getPassword().equals("12345678")) {
token = JJWTUsage.createTokenV1(user.getUsername());
return String.format("login success, token: %s", token);
} else return "登录信息错误";
}
}
控制器类-用户操作
package com.example.springbootauthdemo.controller;
import com.example.springbootauthdemo.param.User;
import com.example.springbootauthdemo.util.JJWTUsage;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserV1Controller {
@PostMapping("/userV1/update")
public Object update(@RequestHeader("token") String token, @RequestBody User user) {
if (JJWTUsage.parseTokenV1(token)) {
return "update user info success.";
}
return "请先认证";
}
}
用户类就是一个简单的 bean:
package com.example.springbootauthdemo.param;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
public class User {
@NotBlank
private String username;
@Min(value = 6)
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
如需深入 jjwt ,请点击 github官方-jjwt
更多: