当前位置: 首页 > article >正文

Java 和 JWT(JSON Web Tokens)实现 token 鉴权

 代码实现:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;

public class JwtAuthExample {
    // 密钥,应该保存在安全的地方,这里仅作示例
    private static final String SECRET_KEY = "yourSecretKey"; 
    // token 过期时间,单位:毫秒
    private static final long EXPIRATION_TIME = 3600000; 

    // 生成 JWT token
    public static String generateToken(String subject, String role) {
        return Jwts.builder()
             .setSubject(subject)
             .claim("role", role) // 添加角色信息,用于鉴权
             .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
             .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
             .compact();
    }

    // 验证 JWT token 并提取角色信息
    public static String validateToken(String token) {
        try {
            Claims claims = Jwts.parser()
                         .setSigningKey(SECRET_KEY)
                         .parseClaimsJws(token)
                         .getBody();
            String subject = claims.getSubject();
            String role = (String) claims.get("role");
            System.out.println("Subject: " + subject);
            System.out.println("Role: " + role);
            return role;
        } catch (Exception e) {
            System.out.println("Invalid token");
            return null;
        }
    }

    // 检查用户是否有权限
    public static boolean hasPermission(String token, String requiredRole) {
        String userRole = validateToken(token);
        if (userRole == null) {
            return false;
        }
        return userRole.equals(requiredRole);
    }

    public static void main(String[] args) {
        String subject = "exampleUser";
        String role = "admin";
        String token = generateToken(subject, role);
        System.out.println("Generated Token: " + token);

        String extractedRole = validateToken(token);
        System.out.println("Extracted Role: " + extractedRole);

        boolean hasPermission = hasPermission(token, "admin");
        System.out.println("Has Permission: " + hasPermission);
    }
}

代码解释

  • SECRET_KEY:这是一个用于签名和验证 JWT 的密钥,在实际应用中应该存储在安全的地方,不能直接硬编码在代码中。
  • EXPIRATION_TIME:定义了 JWT token 的过期时间,这里设置为 1 小时(3600000 毫秒)。
  • generateToken 方法:
    • 使用 Jwts.builder() 创建一个 JWT 构建器。
    • setSubject(subject):设置 JWT 的主题,通常是用户的唯一标识符,例如用户 ID 或用户名。
    • claim("role", role):添加一个自定义的 role 声明,用于存储用户的角色信息,以便后续鉴权使用。
    • setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)):设置 token 的过期时间为当前时间加上 EXPIRATION_TIME
    • signWith(SignatureAlgorithm.HS256, SECRET_KEY):使用 HS256 算法和 SECRET_KEY 对 JWT 进行签名。
    • compact():将构建好的 JWT 压缩成最终的 token 字符串。
  • validateToken 方法:
    • 使用 Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody() 解析并验证 token。
    • claims.getSubject():提取 JWT 的主题。
    • claims.get("role"):提取存储在 role 声明中的角色信息。
    • 如果解析过程中出现异常,将打印 "Invalid token" 并返回 null
  • hasPermission 方法:
    • 调用 validateToken(token) 验证 token 并提取角色信息。
    • 检查提取的角色是否与所需的角色 requiredRole 匹配,从而判断用户是否有权限。

使用说明

  • 请确保在运行代码前,你已经添加了 io.jsonwebtoken 库的依赖。如果你使用的是 Maven,可以在 pom.xml 中添加以下依赖:
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.9.1</version>
    </dependency>
  • 可以根据实际需求修改 SECRET_KEY 和 EXPIRATION_TIME 的值。
  • 对于不同的用户,可以调用 generateToken 方法为其生成包含相应角色信息的 JWT token。
  • 当需要验证用户权限时,调用 hasPermission 方法,传入用户的 token 和所需的角色进行检查。
  • 密钥的安全性至关重要,不能将其硬编码在代码中,应使用更安全的存储方式,如环境变量或密钥管理服务。
  • 在实际应用中,可能需要更复杂的权限管理,例如支持多种角色和权限,此时可以在 JWT 的 claims 中添加更多的自定义声明。
  • 对于过期的 token,应该引导用户重新登录或使用刷新 token 机制来获取新的 token。
  • 要考虑网络安全问题,例如防止 token 泄露和中间人攻击,确保 token 在传输过程中的安全性。

http://www.kler.cn/a/515471.html

相关文章:

  • Android SystemUI——通知栏构建流程(十六)
  • IOS 安全机制拦截 window.open
  • 最新版pycharm如何配置conda环境
  • 用JAVA写算法之输入输出篇
  • E-Prime2实现List嵌套
  • Dart语言的学习路线
  • 【面试常见问题】
  • vue3+elementPlus之后台管理系统(从0到1)(day3-管理员管理)
  • STM32项目分享:智能厨房安全检测系统
  • docker 安装 mysql 详解
  • thinkphp8在使用apidoc时, 4层的接口会有问题 解决办法
  • Kafka-常见的问题解答
  • java提取系统应用的日志中的sql获取表之间的关系
  • html、js、css实现爱心效果
  • 消息队列篇--原理篇--Pulsar(Namespace,BookKeeper,类似Kafka甚至更好的消息队列)
  • I2S是什么通信协议?它如何传输音频数据?它和I2C是什么关系?
  • flutter_学习记录_00_环境搭建
  • 华为OD机试真题---战场索敌
  • 【MySQL】C# 连接MySQL
  • 面向对象编程——类的描述与项目文档
  • AIGC大模型详解(ChatGPT,Cursor,豆包,文心一格)
  • 【Hadoop面试题2025】
  • 鸿蒙harmony json转对象(2)
  • Gin 框架入门实战系列教程
  • C Linux 下常用锁介绍
  • python实战(十五)——中文手写体数字图像CNN分类