美文网首页
JWT 保存的信息,如何在上下文中传递?

JWT 保存的信息,如何在上下文中传递?

作者: 极简博客 | 来源:发表于2023-05-13 11:51 被阅读0次

相信大家都使用过 Jwt ,在其生成的 token 中存储用户信息。在 aop 或者 拦截器 中将对用户的授权token进行认证,验证成功之后将解析出来的用户信息保存在线程的上下文中,以便于在之后的操作中能够随时使用。那么如何保存该值呢?在使用中有遇什么样的问题?你是如何解决的。接下来我讲讲我的做法。

起初我是想通过 request.setAttribute() 完成信息的暂存的 ,的确这种方法也可行。但是如果方法中存在调用异步方法的情况,那么这种方式就会存在问题。此时可以通过传递参数的方式去解决。但是有没有更加优雅的方式呢?于是我继续寻找其它方法:通过了 ThreadLocal 的方式去存储。由于此类的副本数据不会在线程池中传递。于是我使用到了阿里的 TransmittableThreadLocal 去解决线程池无法传递线程本地副本的问题。但在使用的过程中发现了问题,线程池虽传递了本地副本,但是在下一次请求的时候还是保留了旧值。这个结果是由于线程复用导致的,于是我上网查找了相关资料。找到了在创建线程池的时候使用装饰器封装线程,以防止线程池只会在线程初始化的时候将父线程的值拷贝到子线程,也就是一直保留旧值的原因。executor.setTaskDecorator(TtlRunnable::get);

由于想知道TtlRunnable是如何解决问题的,于是查看了它的源码。

  • TtlRunnable::get 将 Runnable 参数传递到 TtlRunnable 的构造方法去创建 TtlRunnable 实例
@Nullable
public static TtlRunnable get(@Nullable Runnable runnable) {
    return get(runnable, false, false);
}

public static TtlRunnable get(@Nullable Runnable runnable, boolean releaseTtlValueReferenceAfterRun, boolean idempotent) {
    ...
    return new TtlRunnable(runnable, releaseTtlValueReferenceAfterRun);
}

private TtlRunnable(@NonNull Runnable runnable, boolean releaseTtlValueReferenceAfterRun) {
    // capturedRef:拷贝副本的引用
    this.capturedRef = new AtomicReference<Object>(capture());
    // 执行逻辑对象
    this.runnable = runnable;
    this.releaseTtlValueReferenceAfterRun = releaseTtlValueReferenceAfterRun;
}
  • 进入 capture() 方法 - 拷贝副本引用
public static Object capture() {
    // 生成快照
    return new Snapshot(captureTtlValues(), captureThreadLocalValues());
}

// 拷贝 ttl 值
private static HashMap<TransmittableThreadLocal<Object>, Object> captureTtlValues() {
    HashMap<TransmittableThreadLocal<Object>, Object> ttl2Value = new HashMap<TransmittableThreadLocal<Object>, Object>();
    for (TransmittableThreadLocal<Object> threadLocal : holder.get().keySet()) {
        ttl2Value.put(threadLocal, threadLocal.copyValue());
    }
    return ttl2Value;
}

// 拷贝 threadLocal 值
private static HashMap<ThreadLocal<Object>, Object> captureThreadLocalValues() {
    final HashMap<ThreadLocal<Object>, Object> threadLocal2Value = new HashMap<ThreadLocal<Object>, Object>();
    for (Map.Entry<ThreadLocal<Object>, TtlCopier<Object>> entry : threadLocalHolder.entrySet()) {
        final ThreadLocal<Object> threadLocal = entry.getKey();
        final TtlCopier<Object> copier = entry.getValue();

        threadLocal2Value.put(threadLocal, copier.copy(threadLocal.get()));
    }
    return threadLocal2Value;
}
  • 执行任务
public void run() {
    
    // 获取上一步的快照,主线程传递下来的ThreadLocal的值
    final Object captured = capturedRef.get();
    if (captured == null || releaseTtlValueReferenceAfterRun && !capturedRef.compareAndSet(captured, null)) {
        throw new IllegalStateException("TTL value reference is released after run!");
    }
    // 在执行任务之前,将 captured 的 ThreadLocal值设置到当前任务线程,返回初始化时的备份值 *
    final Object backup = replay(captured);
    try {
        runnable.run();
    } finally {
        // 回滚为初始化备份值
        restore(backup);
    }
}

以上是我的做法,你的做法是怎样的呢?或者我的方法有没有不足的地方?不吝赐教。

相关文章

  • JWT认证机制

    JWT认证机制session不可跨域,用户信息保存在服务器端;JWT可以跨域,用户信息保存在浏览器; JWT工作原...

  • php实现jwt

    JWT是什么 JWT是json web token缩写。它将用户信息加密到token里,服务器不保存任何用户信息。...

  • jwt web token php 实现

    JWT是什么 JWT是json web token缩写。它将用户信息加密到token里,服务器不保存任何用户信息。...

  • php实现JWT(json web token)鉴权实例

    JWT是什么 JWT是json web token缩写。它将用户信息加密到token里,服务器不保存任何用户信息。...

  • JWT(JSON Web Token)的原理的构造及使用

    JWT是什么 JWT是json web token缩写。它将用户信息加密到token里,服务器不保存任何用户信息。...

  • php 使用jwt

    JWT是什么 JWT是json web token缩写。它将用户信息加密到token里,服务器不保存任何用户信息。...

  • Java:SpringBoot+MybatisPlus+Gene

    续Java:SpringBoot+Jwt+Shiro+MybatisPlus+Swagger集成 在上文中描述了项...

  • 使用spring security + JWT 权限认证

    JWT 简介 JWT是 json web token 缩写。它将用户信息加密到token里,服务器不保存任何用户信...

  • 使用spring security + JWT 权限认证

    JWT 简介 JWT是 json web token 缩写。它将用户信息加密到token里,服务器不保存任何用户信...

  • jwt学习

    jwt是如何验证的? jwt保存在客户端,每次请求时都将其放在header中,这样服务器接收到请求后,取出jwt进...

网友评论

      本文标题:JWT 保存的信息,如何在上下文中传递?

      本文链接:https://www.haomeiwen.com/subject/uloysdtx.html