繁体   English   中英

如何在 Quarkus 中使用用户 session?

[英]How to use a user session in Quarkus?

我有一些数据将通过Authorization Header中的令牌进行验证和检索。那么我如何设置一些session中的数据以便它可以在另一个class中使用而无需再次验证?

这是我的过滤器 class

override fun filter(@Context context: ContainerRequestContext) {
    val token = context.getHeaderString("Authorization")
    verify() // FirebaseAuth verify
    val id = token.id //retrieved from token
    val name = token.name //retrieved from token
}

在我的资源文件中

@ApplicationScoped
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/foo")
class FooResource {
    @GET
    @Path("/")
    fun foo(): Response {
        val id = //how can I get the id from my token without verifying it again?
    }
}

如何在不再次验证我的令牌的情况下获取 ID?

我正在使用 Firebase 来生成和验证我的令牌。

将从令牌中检索到的数据存储在 session 中并使其可供其他类使用的一种方法是使用共享上下文 object。您可以将数据添加到过滤器 class 中的上下文 object,然后在资源 class 中检索它。例如:

override fun filter(@Context context: ContainerRequestContext) {
    val token = context.getHeaderString("Authorization")
    verify() // FirebaseAuth verify
    val id = token.id //retrieved from token
    val name = token.name //retrieved from token
    context.setProperty("id", id)
    context.setProperty("name", name)
}

@GET
@Path("/")
fun foo(@Context context: ContainerRequestContext): Response {
    val id = context.getProperty("id")
}

或者,您可以使用ThreadLocal变量来存储和检索数据。 这样可以避免再次验证token,但是这种方式不是线程安全的,如果你的应用运行在多线程环境下,应该使用共享上下文object代替。

更新 1

有没有办法让我不需要在我的每个 function 中声明上下文? 例如把它作为一个扩展? 还是在资源层面声明一次? 我不确定这是否可以实现

是的,您可以通过将上下文作为 class 的字段注入,使资源 class 中的所有方法都可用。

您可以在 ContainerRequestContext class 上定义一个扩展 function。这样,您就不必在每个 class function 中使用上下文变量。

fun ContainerRequestContext.getId(): String? = this.getProperty("id") as String?

然后在您的资源 class 中,您可以将上下文作为字段注入并使用扩展 function 来检索 ID:

@Context
lateinit var context: ContainerRequestContext

@GET
@Path("/")
fun foo(): Response {
    val id = context.getId()
    // ...
}

或者,您也可以使用 CDI 创建一个存储 ID 和名称的 singleton bean,这样您就可以从应用程序中的任何 class 中检索 ID 和名称,而无需依赖请求上下文。

@ApplicationScoped
class TokenStorage {
    var id: String? = null
    var name: String? = null
}

然后你可以在任何你想要的 class 中注入这个 bean,并在过滤器 class 中验证令牌时设置 id 和名称。

@Inject
lateinit var tokenStorage: TokenStorage

override fun filter(@Context context: ContainerRequestContext) {
    val token = context.getHeaderString("Authorization")
    verify() // FirebaseAuth verify
    tokenStorage.id = token.id
    tokenStorage.name = token.name
}

在您的资源 class 中,您可以使用 tokenStorage bean 来检索 ID 和名称

@GET
@Path("/")
fun foo(): Response {
    val id = tokenStorage.id
    // ...
}

需要注意的是,这种方式会保留memory中的token数据,用户退出时需要手动清除。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM