java —— token的使用工具类

本文探讨了HTTP无状态特性下,如何通过Session和Token机制实现用户验证。详细介绍了Token的生成、加密及解析过程,展示了其在用户验证中的优势,如持久化方便、安全性高。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

          http是个无差别访问,就是无论你访问多少次,服务器都无法知道你是谁。所以后来有了session出现来解决用户验证的问题,但是session是个很重要的资源,往往保存少量且重要的数据。但是随着用户量增大,session所占的内存也越来越大,服务器的压力也大,所有后面出现了token,它把session的数据加密,可以保存进redis或者本地数据库,需要用户验证的时候再拿出来解析,还可以设置超时时间,某种程度上可以取代session的验证或者与之结合来验证用户,而且最重要的是token持久化很方便,加密后的token字符串你可以随意保存,并且token的加密可自定义,也不怕别人截获token解析出用户数据。现在已经接触了不少项目在用户信息中添加了token字段,来保存加密后的token数据。

 

完整的token工具类(含数据转化和加密方法):JavaWebToken.java

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;
import java.util.Map;

 
public class JavaWebToken {

    private static Logger log = LoggerFactory.getLogger(JavaWebToken.class);

    //该方法使用HS256算法和Secret:bankgl生成signKey
    private static Key getKeyInstance() {
        //We will sign our JavaWebToken with our ApiKey secret
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary("abcdefghijkl");//加密,里面的字符串可自行定义
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
        return signingKey;
    }

    /**使用HS256签名算法和生成的signingKey最终的Token,claims中是有效载荷
     * @param claims  待转化的数据
     * @return  token字符串
     */
    public static String createJavaWebToken(Map<String, Object> claims) {
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        return Jwts.builder()
                .setClaims(claims)
                .setExpiration(new Date(nowMillis + 1000*60*60*24*7))//超时时间,设置为7天
                .setIssuedAt(now)
                .setNotBefore(now)
                .signWith(SignatureAlgorithm.HS256, getKeyInstance())
                .compact();
    }

    /**解析Token,同时也能验证Token,当验证失败返回null
     * @param jwt  token字符串
     * @return  解析的数据
     */
    public static Map<String, Object> parserJavaWebToken(String jwt) {
        try {
            Map<String, Object> jwtClaims =
                    Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwt).getBody();
            return jwtClaims;
        } catch (Exception e) {
            log.error("json web token verify failed : " + e.getMessage());
            return null;
        }
    }
}

 

测试方法:

public static void main(String[] args) throws UnsupportedEncodingException {
        Map<String, Object> claims = new HashMap<String,Object>();
    	//模拟添加session中的用户数据
    	claims.put("id", "555");
    	claims.put("name", "小白");
    	claims.put("pass", "555");
    	//转成token
    	String myToken = JavaWebToken.createJavaWebToken(claims);
    	System.out.println("我的token数据:" + myToken);
    	//token转化为原数据
    	Map<String, Object> myTokenMap = JavaWebToken.parserJavaWebToken(myToken);
    	System.out.println("token转化为Map:" + myTokenMap);

}

 

结果:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/E:/maven/jar/org/slf4j/slf4j-simple/1.7.21/slf4j-simple-1.7.21.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/E:/maven/jar/org/slf4j/slf4j-log4j12/1.7.7/slf4j-log4j12-1.7.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.SimpleLoggerFactory]
我的token数据:eyJhbGciOiJIUzI1NiJ9.eyJuYmYiOjE1NTczODM1MTIsInBhc3MiOiI1NTUiLCJuYW1lIjoi5bCP55m9IiwiaWQiOiI1NTUiLCJleHAiOjE1NTc5ODgzMTIsImlhdCI6MTU1NzM4MzUxMn0.2osIe0ULpaLtivMa_PNN_8lK5rLT6MWriMV6au5zfJc
token转化为Map:{nbf=1557383512, pass=555, name=小白, id=555, exp=1557988312, iat=1557383512}

 

### Sa-Token使用方法及实现地址白名单限制 以下是对 Sa-Token 工具库的详细介绍以及如何在其基础上实现地址白名单限制的具体方法。 --- #### 1. **Sa-Token 简介** Sa-Token 是一款轻量级 Java 权限认证框架,专注于解决微服务架构下的会话管理、单点登录(SSO)、权限控制等问题。它具有简单易用的特点,开发者只需调用核心 API 即可快速完成用户认证与授权操作[^1]。 --- #### 2. **基本使用流程** ##### (1)初始化配置 在 Spring Boot 或其他 Java 项目中引入 Sa-Token 依赖后,需进行必要的初始化设置。例如,在 `application.yml` 文件中指定 Redis 地址以便支持分布式环境下的 Session 共享: ```yaml sa-token: timeout: 28800 # token有效期,默认单位秒 activity-timeout: 0 # 如果为正数,则启用基于滑动窗口的活动超时策略 is-concurrent: true # 是否允许多设备同时在线 redis-enable: true # 开启redis缓存支持 redis-host: localhost:6379 # redis连接地址 ``` 随后按照官方文档指引编写自定义插件类并注册到容器中[^4]。 ##### (2)用户登录认证 借助 StpUtil 提供的基础方法即可轻松达成用户的签发 Token 功能: ```java // 登录成功后的处理逻辑 Object loginId = "10001"; // 用户唯一标识符 StpUtil.login(loginId); String tokenValue = StpUtil.getTokenValue(); // 获取当前用户的token值 System.out.println("生成的新Token:" + tokenValue); ``` 此处需要注意的是,当向客户端传递最终形成的 Bearer 类型 Tokens 时,请务必遵循标准格式要求——即确保 Token 字串前附带 `"Bearer "` 关键字作为前缀[^2]。 --- #### 3. **实现地址白名单限制** 针对特定场景需求,比如只允许某些固定范围内的 URL 路径能够接收来自外部携带有效 Tokens 请求访问的情形下,可通过如下手段加以管控: ##### (1)定义全局变量存储合法路径集合 类似于前面提到过的做法,先建立一个包含所有许可目标位置字符串形式表示的数据结构对象: ```java Set<String> whiteListPaths = new HashSet<>(Arrays.asList("/api/user/info", "/api/order/list")); ``` ##### (2)拦截器校验机制设计 接着利用 Servlet Filter 或者 AOP 切面技术等方式捕获每一次 HTTP 进程发起动作,并逐一核对其意图前往之处是否处于前述所列范畴之中: ```java @Component public class AuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String uri = request.getRequestURI(); // 检查 URI 是否存在于白名单内 if (!whiteListPaths.contains(uri)) { throw new RuntimeException("非法请求路径!"); } // 执行 sa-token 鉴权检查 if (!StpUtil.isLogin()) { throw new RuntimeException("尚未登录或已登出!"); } return true; } } ``` 上述代码片段展示了如何结合 Sa-Token 自身能力对外界传来的每笔交易行为展开双重维度上的严格审查:一方面确认其试图抵达的目标节点确实已被纳入预设清单;另一方面则依据内部记录状态核实发送方主体资格的真实性[^3]。 --- #### 4. **总结说明** 通过本文介绍可以看出,采用 Sa-Token 不仅能极大简化传统意义上围绕着 Sessions Cookies 构建起来的一系列繁杂事务性工作负担,而且还能灵活适应各类新兴趋势变化所带来的挑战。与此同时,辅之以恰当合理的防护措施安排,更是能够让整体系统运行更加稳健可靠。 --- ###
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值