首页 > 解决方案 > 如何在拦截器android改造时检查令牌过期?

问题描述

我想自己处理令牌到期并发送新令牌的请求。我有这样的条件:

sp.getLong("expires_in", 0) - sp.getLong("time_delta", 0) - System.currentTimeMillis() / 1000 <= 60

此条件检查我的令牌何时过期并且我必须从拦截器发送新请求。我也看到了这个问题。我创建了这样的拦截器:

class RefreshTokens(cont: Context) : Interceptor{
    val context = cont
    override fun intercept(chain: Interceptor.Chain): Response {
        var tokenIsUpToDate = false
        val sp = context.getSharedPreferences("app_data", 0)
        if (sp.getLong("expires_in", 0) - sp.getLong("time_delta", 0) - System.currentTimeMillis() / 1000 <= 60) {
            Singleton.apiService(context).getNewToken(ReqAccessToken(context.getSharedPreferences("app_data", 0).getString("refresh_token", ""))).enqueue(object : Callback<ResNewTokens>, retrofit2.Callback<ResNewTokens> {
                override fun onResponse(call: Call<ResNewTokens>, response: retrofit2.Response<ResNewTokens>) {
                    if (response.isSuccessful) {
                        tokenIsUpToDate = true
                    }
                }

                override fun onFailure(call: Call<ResNewTokens>, t: Throwable) {

                }

            })

            return if (tokenIsUpToDate) {
                chain.proceed(chain.request())
            } else {
                chain.proceed(chain.request())
            }

        } else {
            val response = chain.proceed(chain.request())
            when (response.code) {
                401->{
                    chain.request().url
                    response.request.newBuilder()
                            .header("Authorization", "Bearer " + context.getSharedPreferences("app_data", 0).getString("access_token", "")!!)
                            .build()
                }
                500 -> {
                    Toast.makeText(context, context.getString(R.string.server_error_500), Toast.LENGTH_SHORT).show()
                }
            }
            return response
        }
    }
}

我无法想象如何在我的代码中添加返回条件。我知道,Authentificator但是当我使用它时,我又发送了一个请求,该响应给我 401 令牌更新错误。当我使用Authentificator我发送这样的请求:

  1. 带有旧 access_token 的请求 -> 401 错误
  2. 请求新令牌 -> 200 OK
  3. 使用新的 access_token 请求 -> 200 OK

所以我想删除 1 个请求,这将给出错误并发送新令牌的请求。但我有问题:

  1. 我不知道如何修复我的拦截器来解决这个任务
  2. 我不知道如何重复我将在 Authentificator 中发出的请求

也许有人知道如何解决我的问题?

标签: androidretrofit2okhttp

解决方案


是的,这太简单了,不采取很困难,我也有同样的问题,但我是这样解决的

因此,当令牌过期时,Retrofit 会给出

错误代码 = 401

所以你需要保存用户的数据使用sharedPref userEmailuserName以及userPassword所以

当用户收到令牌过期消息或错误代码 401时,您需要调用一个方法再次登录用户,以使用useremailuserpassword向用户显示任何内容,然后生成一个新令牌,然后将生成的令牌发送到服务器,它将在这种情况下工作

我希望这会有所帮助


推荐阅读