拦截刷新令牌 GRPC 的调用

Art*_*RiT 5 android interceptor kotlin grpc

我在项目中使用带有 proto 的 GRPC,并且有 KEY 和 AUTHORITY 令牌来访问服务器 API。所以,我需要使用我的权限更新密钥。我正在像这样建立频道:

OkHttpChannelBuilder.forAddress(host, port)
        .usePlaintext()
        .intercept(auth, logger)
        .build()
Run Code Online (Sandbox Code Playgroud)

我的拦截器看起来像:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

1)向服务器发送请求;

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

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

小智 -2

如果您想这样做,我认为您必须完全按照您所描述的那样在应用程序级别处理它。这是因为 gRPC 不知道您的应用程序级别令牌。

  1. 进行 RPC
  2. 请注意,RPC 由于令牌过期而失败
  3. 调用刷新令牌的代码
  4. 重复

您指的验证器是什么?