java 如何在Quarkus中使用用户会话?

drnojrws  于 2023-01-24  发布在  Java
关注(0)|答案(1)|浏览(192)

我有一些数据将通过Authorization Header中的token进行验证和检索。那么我如何在某个会话中设置数据,以便它可以在另一个类中使用,而无需再次验证它?
下面是我的过滤器类

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?
    }
}

我如何在不再次验证我的令牌的情况下获得get id?
我正在使用Firebase生成和验证我的令牌。

t9aqgxwy

t9aqgxwy1#

将从令牌检索到的数据存储在会话中并使其可用于其他类的一种方法是使用共享上下文对象。可以将数据添加到筛选器类中的上下文对象,然后在资源类中检索它。例如:

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变量来存储和检索数据,这样可以避免再次验证令牌,但这种方法不是线程安全的,如果您的应用程序在多线程环境中运行,则应该改用共享上下文对象。

更新1

有没有一种方法可以让我不需要在我的每个函数中声明上下文?例如,把它作为一个扩展?或者在资源层中声明一次?我不确定这是否可行
是的,您可以通过将上下文作为类的一个字段注入,使其对资源类中的所有方法都可用。
你可以在ContainerRequestContext类上定义一个扩展函数,这样,你就不必在每个类函数中都使用context变量。

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

然后,在资源类中,可以将上下文作为字段注入,并使用扩展函数检索id:

@Context
lateinit var context: ContainerRequestContext

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

或者,您也可以使用CDI创建一个存储id和name的单例bean,这样您就可以从应用程序中的任何类检索id和name,而不必依赖于请求上下文。

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

然后,您可以将这个bean注入到任何您想要的类中,并在过滤器类中验证令牌时设置id和name。

@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
}

在资源类中,可以使用tokenStorage bean检索id和name

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

需要注意的是,此方法会将令牌数据保留在内存中,您必须在用户注销时手动将其清除。

相关问题