Java Spring Boot 结合 jjwt 实现 JWT 认证

1,469 阅读1分钟

在 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

更多: