gpt4 book ai didi

android - 拦截调用以刷新 token GRPC

转载 作者:行者123 更新时间:2023-11-29 02:26:45 25 4
gpt4 key购买 nike

我在我的项目中使用 GRPC 和 proto,我有 KEY 和 AUTHORITY token 来访问服务器 API。所以,我需要使用我的 AUTHORITY 更新 KEY。我正在这样构建 channel :

OkHttpChannelBuilder.forAddress(host, port)
.usePlaintext()
.intercept(auth, logger)
.build()

我的拦截器看起来像:

class AuthClientInterceptor(
private val prefs: Preferences,
private val keyApi: KeyApi) : ClientInterceptor {

companion object {
private const val ACCESS_TOKEN = "authorization"
}

override fun <ReqT : Any?, RespT : Any?> interceptCall(method: MethodDescriptor<ReqT, RespT>?,
callOptions: CallOptions?,
next: Channel): ClientCall<ReqT, RespT> {

val call = next.newCall(method, callOptions)

val callForwarding = object : ClientInterceptors.CheckedForwardingClientCall<ReqT, RespT>(call) {
override fun checkedStart(responseListener: Listener<RespT>?, headers: Metadata) {

synchronized(this@AuthClientInterceptor) {
val keyCreated = prefs.getAccessKeyCreated()
val keyExpires = prefs.getAccessKeyExpires()
val currentTime = System.currentTimeMillis()
if (currentTime < keyCreated || currentTime > keyExpires) {
keyApi.issueNewKey(prefs.getAuthority())
.map { it.data }
.doOnSuccess { prefs.setAccessKey(it.token) }
.doOnSuccess { prefs.setAccessKeyCreated(it.createdDate) }
.doOnSuccess { prefs.setAccessKeyExpires(it.expiresDate) }
.blockingGet()
}
}

val keyData = Metadata.Key.of(ACCESS_TOKEN, Metadata.ASCII_STRING_MARSHALLER)
if (headers[keyData] == null) {
headers.put(keyData, "Bearer ${prefs.getAccessKey()}")
}
call.start(responseListener, headers)
}
}
return callForwarding
}
}

如您所见,我只检查当前时间并将其与 token 创建日期和到期日期进行比较。

所以,我不喜欢那样。我想实现这个:

1) 向服务器发送请求;

2) 检查响应。如果这意味着我的 KEY 已过期,则同步刷新 key 并重复请求(如身份验证器)。

但我没有找到解决方案或任何有关使用 gRPC 实现此功能的有用信息。有人可以帮助我吗?

最佳答案

这是您可以使用的完整客户端拦截器类。

class Interceptor() : ClientInterceptor {

override fun <ReqT : Any?, RespT : Any?> interceptCall(method: MethodDescriptor<ReqT, RespT>?, callOptions: CallOptions?, next: Channel?): ClientCall<ReqT, RespT> {

return object : ClientCall<ReqT, RespT>() {

var listener: Listener<RespT>? = null
var metadata: Metadata? = null
var message: ReqT? = null
var request = 0
var call: ClientCall<ReqT, RespT>? = null

override fun start(responseListener: Listener<RespT>?, headers: Metadata?) {
this.listener = responseListener
this.metadata = headers
}

override fun sendMessage(message: ReqT) {
assert(this.message == null)
this.message = message
}

override fun request(numMessages: Int) {
request += numMessages
assert(this.message == null)
}

override fun isReady(): Boolean {
return false
}

override fun halfClose() {

startCall(object : ForwardingClientCallListener<RespT>() {

var delegate: Listener<RespT>? = null

override fun onReady() {
delegate = listener
super.onReady()
}

override fun delegate(): Listener<RespT> {
if (delegate == null) {
throw IllegalStateException()
}
return delegate!!
}

override fun onClose(status: Status?, trailers: Metadata?) {
if (delegate == null) {
super.onClose(status, trailers)
return
}
if (!needToRetry(status, trailers)) {
delegate = listener
super.onClose(status, trailers)
return
}
startCall(listener) // Only retry once
}

private fun needToRetry(status: Status?, trailers: Metadata?): Boolean {
if (status?.code?.toStatus() == UNAUTHENTICATED) {
Log.e("code", status?.code.toString())
return true
}
return false
}
})
}

private fun startCall(listener: Listener<RespT>?) {
call = next?.newCall(method, callOptions)
val headers = Metadata()
headers.merge(metadata)
call?.start(listener, headers)
assert(this.message != null)
call?.request(request)
call?.sendMessage(message)
call?.halfClose()
}

override fun cancel(message: String?, cause: Throwable?) {
if (call != null) {
call?.cancel(message, cause)
}
listener?.onClose(Status.CANCELLED.withDescription(message).withCause(cause), Metadata())
}
}
}
}

它缓冲消息并重试,您可以在 needToRetry(status, trailers) 中添加您的逻辑

更多信息可以访问这个GitHub link.

关于android - 拦截调用以刷新 token GRPC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51840892/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com