[java][JwtUtils ]生成token以及校验token相关方法

该工具类JwtUtils主要用于生成和解析JWT(JSON Web Token),提供了以下功能:

  1. 生成Token: 提供了两种方法generateTokenExpireInMinutesgenerateTokenExpireInSeconds,分别支持以分钟和秒为单位设置Token过期时间。生成Token时,使用私钥对Token进行签名,确保Token的安全性和不可篡改性。

  2. 解析Token: 提供了getInfoFromToken方法,使用公钥验证Token的合法性,并从中提取出载荷信息(如用户信息)。支持提取泛型类型的用户信息,便于处理不同类型的数据。

  3. 核心功能:

    • 使用Jwts工具类构建和解析Token。

    • 支持自定义载荷数据,通过claim方法将用户信息嵌入Token。

    • 自动生成唯一的JWT ID(JTI),确保Token的唯一性。

    • 提供了两种重载的getInfoFromToken方法,一种用于提取完整载荷信息,另一种用于提取用户信息和过期时间。

  4. 依赖工具:

    • 使用JsonUtils工具类进行JSON序列化和反序列化,处理载荷中的复杂对象。

    • 使用DateTime类处理过期时间,支持灵活的时间计算。

适用场景:

适用于需要通过JWT进行身份验证或数据传输的系统,尤其适用于分布式系统中的跨服务认证。

import com.itheima.domain.Payload;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.joda.time.DateTime;

import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;
import java.util.UUID;

/**
 * 生成token以及校验token相关方法
 */
public class JwtUtils {

    private static final String JWT_PAYLOAD_USER_KEY = "user";

    /**
     * 私钥加密token
     *
     * @param userInfo   载荷中的数据
     * @param privateKey 私钥
     * @param expire     过期时间,单位分钟
     * @return JWT
     */
    public static String generateTokenExpireInMinutes(Object userInfo, PrivateKey privateKey, int expire) {
        return Jwts.builder()
                .claim(JWT_PAYLOAD_USER_KEY, JsonUtils.toString(userInfo))
                .setId(createJTI())
                .setExpiration(DateTime.now().plusMinutes(expire).toDate())
                .signWith(privateKey, SignatureAlgorithm.RS256)
                .compact();
    }

    /**
     * 私钥加密token
     *
     * @param userInfo   载荷中的数据
     * @param privateKey 私钥
     * @param expire     过期时间,单位秒
     * @return JWT
     */
    public static String generateTokenExpireInSeconds(Object userInfo, PrivateKey privateKey, int expire) {
        return Jwts.builder()
                .claim(JWT_PAYLOAD_USER_KEY, JsonUtils.toString(userInfo))
                .setId(createJTI())
                .setExpiration(DateTime.now().plusSeconds(expire).toDate())
                .signWith(privateKey, SignatureAlgorithm.RS256)
                .compact();
    }

    /**
     * 公钥解析token
     *
     * @param token     用户请求中的token
     * @param publicKey 公钥
     * @return Jws<Claims>
     */
    private static Jws<Claims> parserToken(String token, PublicKey publicKey) {
        return Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token);
    }

    private static String createJTI() {
        return new String(Base64.getEncoder().encode(UUID.randomUUID().toString().getBytes()));
    }

    /**
     * 获取token中的用户信息
     *
     * @param token     用户请求中的令牌
     * @param publicKey 公钥
     * @return 用户信息
     */
    public static <T> Payload<T> getInfoFromToken(String token, PublicKey publicKey, Class<T> userType) {
        Jws<Claims> claimsJws = parserToken(token, publicKey);
        Claims body = claimsJws.getBody();
        Payload<T> claims = new Payload<>();
        claims.setId(body.getId());
        claims.setUserInfo(JsonUtils.toBean(body.get(JWT_PAYLOAD_USER_KEY).toString(), userType));
        claims.setExpiration(body.getExpiration());
        return claims;
    }

    /**
     * 获取token中的载荷信息
     *
     * @param token     用户请求中的令牌
     * @param publicKey 公钥
     * @return 用户信息
     */
    public static <T> Payload<T> getInfoFromToken(String token, PublicKey publicKey) {
        Jws<Claims> claimsJws = parserToken(token, publicKey);
        Claims body = claimsJws.getBody();
        Payload<T> claims = new Payload<>();
        claims.setId(body.getId());
        claims.setExpiration(body.getExpiration());
        return claims;
    }
}

### 后端 Token 的实现与管理 #### 什么是 TokenToken 是一种用于身份验证和授权的技术手段,通常是一个字符串形式的数据结构。它可以在客户端和服务端之间传递,用来证明用户的合法性和权限范围。 在现代 Web 应用程序中,Token 被广泛应用于无状态的身份认证机制中。相比于传统的 Session 认证方式,Token 更适合分布式系统的设计[^1]。 --- #### Token生成过程 Token生成一般由后端完成,以下是其主要流程: 1. **用户登录** 用户通过用户名和密码向服务器发起登录请求。如果验证成功,则进入下一步操作。 2. **创建 Token** 使用特定算法(如 JWT, JSON Web Token),结合用户信息和其他元数据生成一个唯一的 Token 字符串。此过程中可以设置过期时间、签名密钥等参数来增强安全性[^3]。 3. **存储 Token** 将生成好的 Token 返回给前端,并建议将其保存至 HTTP-only Cookie 或 LocalStorage 中以便后续使用。同时也可以选择将该 Token 存储于 Redis 数据库里关联一些额外的信息比如用户 ID 等[^2]。 --- #### 如何验证 Token? 每当客户端发出新的 API 请求时,都需要附带之前收到的那个有效期内未被篡改过的 Access Token 。具体来说就是把它放在 HTTP Headers 下面名为 `Authorization` 的字段前缀加上单词 Bearer 形成最终格式如下所示: ```http GET /api/resource HTTP/1.1 Host: example.com Authorization: Bearer <your_token_here> ``` 随后服务端会对这个传来的凭证做一系列校验工作包括但不限于检查有效期以及核对其内部负载是否匹配预期等等[^4]。 一旦发现任何异常情况比如说超出了允许的时间窗口或者发现了非法修改痕迹的话都应该立即拒绝此次访问并可能采取进一步措施例如注销对应账户下的所有活跃连接以防潜在威胁扩散开来[^5]。 --- #### 安全注意事项 为了保障整个系统的健壮性,在实际开发当中还需要考虑以下几个方面的问题: - 设置合理的生命周期长度避免长期暴露风险; - 对敏感操作单独设立更严格的二次确认逻辑减少误触发概率; - 部署 HTTPS 协议加密通信链路防止中间人攻击窃取机密资料; --- ### 示例代码:Spring Boot 实现简单的 Token 登录功能 下面给出一段基于 Spring Security 和 JwtUtils 工具类构建基本框架的小例子供参考学习之用: ```java // 导入必要的依赖项... @RestController public class AuthController { @Autowired private UserService userService; @PostMapping("/login") public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) { Authentication authentication = authenticationManager.authenticate( new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword())); SecurityContextHolder.getContext().setAuthentication(authentication); String jwt = tokenProvider.generateToken(authentication); // 创建JWT令牌 return ResponseEntity.ok(new JwtResponse(jwt)); } } ``` 上述片段展示了如何利用自定义的服务对象去处理来自表单提交过来的数据包并通过内置的安全组件来进行初步筛选过滤之后再调用专门负责生产数字证书的方法得到结果最后封装好反馈回去结束一轮交互周期. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

awonw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值