如何解决如何访问服务中的标头?
我正在尝试在后端处理 gRPC 中的 JWT 身份验证。我可以在拦截器中提取 JWT,但如何在我的服务中访问它?我认为应该使用 CoroutineContextServerInterceptor 来完成,但这不起作用:
val jwtKey: Context.Key<String> = Context.key("jwtKey")
fun main() {
ServerBuilder.forPort(8980).intercept(UserInjector).addService(MyService).build().start().awaitTermination()
}
object UserInjector : CoroutineContextServerInterceptor() {
override fun coroutineContext(call: ServerCall<*,*>,headers: Metadata): CoroutineContext {
val jwtString = headers.get(Metadata.Key.of("jwt",Metadata.ASCII_STRING_MARSHALLER))
println("coroutineContext: $jwtString")
return GrpcContextElement(Context.current().withValue(jwtKey,jwtString))
}
}
object MyService : MyServiceGrpcKt.MyServiceCoroutineImplBase() {
override suspend fun testingJWT(request: Test.MyRequest): Test.MyResponse {
println("testingJWT: ${jwtKey.get()}")
return Test.MyResponse.getDefaultInstance()
}
}
输出:
coroutineContext: something
testingJWT: null
解决方法
我认为你需要在它自己的协程上下文元素中传播它。
class JwtElement(val jwtString: String) : CoroutineContext.Element {
companion object Key : CoroutineContext.Key<JwtElement>
override val key: CoroutineContext.Key<JwtElement>
get() = Key
}
object UserInjector : CoroutineContextServerInterceptor() {
override fun coroutineContext(call: ServerCall<*,*>,headers: Metadata): CoroutineContext {
val jwtString = headers.get(Metadata.Key.of("jwt",Metadata.ASCII_STRING_MARSHALLER))
println("coroutineContext: $jwtString")
return JwtElement(jwtString)
}
}
object MyService : MyServiceGrpcKt.MyServiceCoroutineImplBase() {
override suspend fun testingJWT(request: Test.MyRequest): Test.MyResponse {
println("testingJWT: ${coroutineContext[JwtElement]}")
return Test.MyResponse.getDefaultInstance()
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。