【问题标题】:How do Refresh token api call and continue the apis in Retrofit2如何刷新令牌api调用并继续Retrofit2中的api
【发布时间】:2019-08-01 10:39:11
【问题描述】:

我必须为 API 调用实现 Retrofit2。在尝试实现拦截器以执行刷新令牌 api 调用并继续当前的 api cals, 由于响应如下所示,我们无法执行 authtoken 失败检查

{
    "error": "invalid_grant",
    "error_description": "Token needs refresh",
    "mode": "dev",
    "needs_refresh": true,
    "statusCode": 400,
    "success": false,
    "url": "/transactions"
}

我们如何在拦截器中处理此响应并执行刷新令牌 api 调用。

这就是我的拦截器的样子。我想检查键“needs_refresh”来执行 getNewToken()

override fun intercept(chain: Interceptor.Chain?): Response {
        var request = chain!!.request()
        var response = chain.proceed(request)

        if(response.code()==400) {

           getNewToken()
        }
        val token: String = MyApp.prefs[PrefConstants.KEY_PREF_ACCESS_TOKEN,""]
        if(!token.isEmpty())
        request = request?.newBuilder()
                ?.header("Authorization", "Bearer " + token)
                ?.build()
        else
            request = request?.newBuilder()
                    ?.build()
        return chain.proceed(request)
    }

【问题讨论】:

  • 您可以在响应中获取状态码。
  • 确保你的 getNewToken() 方法有使用 execute() 的改造调用,而不是 enqueue() ?
  • 确定我的 getNewtoken() 使用相同的想法。但我的问题是从错误中识别我们是否需要执行 getNewToken 。我想检查“needs_refresh”键

标签: android kotlin retrofit retrofit2 interceptor


【解决方案1】:

为您的响应创建一个模型类,如下所示。

public class ResponseModel{

@SerializedName("mode")
private String mode;

@SerializedName("needs_refresh")
private boolean needsRefresh;

@SerializedName("error_description")
private String errorDescription;

@SerializedName("success")
private boolean success;

@SerializedName("error")
private String error;

@SerializedName("url")
private String url;

@SerializedName("statusCode")
private int statusCode;

public void setMode(String mode){
    this.mode = mode;
}

public String getMode(){
    return mode;
}

public void setNeedsRefresh(boolean needsRefresh){
    this.needsRefresh = needsRefresh;
}

public boolean isNeedsRefresh(){
    return needsRefresh;
}

public void setErrorDescription(String errorDescription){
    this.errorDescription = errorDescription;
}

public String getErrorDescription(){
    return errorDescription;
}

public void setSuccess(boolean success){
    this.success = success;
}

public boolean isSuccess(){
    return success;
}

public void setError(String error){
    this.error = error;
}

public String getError(){
    return error;
}

public void setUrl(String url){
    this.url = url;
}

public String getUrl(){
    return url;
}

public void setStatusCode(int statusCode){
    this.statusCode = statusCode;
}

public int getStatusCode(){
    return statusCode;
}

}

更新了你的拦截

override fun intercept(chain: Interceptor.Chain?): Response {
        
        var request = chain!!.request()
        var response = chain.proceed(request)

        var responseModel = ResponseModel()
        var gson = Gson();
       

        if(response.getCode() == 400) {
 responseModel = gson.fromJson(response.body()?.string(), ResponseModel::class.java);
if(responseModel.isNeedsRefresh()){
            getNewToken()
}
        }
        val token: String = MyApp.prefs[PrefConstants.KEY_PREF_ACCESS_TOKEN,""]
        if(!token.isEmpty())
        request = request?.newBuilder()
                ?.header("Authorization", "Bearer " + token)
                ?.build()
        else
            request = request?.newBuilder()
                    ?.build()
        return chain.proceed(request)
    }

【讨论】:

  • 是的,这是个好主意,但我没有从 response.body().toString() 得到 json
  • 你在 response.body().toString() 中得到了什么?
  • 它的对象名。但是,现在我得到了我们必须使用的答案尝试使用 body().string() 而不是 body().toString(),请您更改它,我将其标记为答案。
【解决方案2】:

我建议你在改造的同时使用 okhttp,

class NetworkInterceptor @Inject constructor(val context: Context) : Interceptor {

override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        var response = request.proceed(request)
        if(response?.code()==400){
            //you can refresh your token here and chain your calls 
         }
     return response;
   }
}

【讨论】:

  • 但是 400 也会出现登录凭据错误或其他一些 api。我想通过检查错误响应中的“needs_refresh”键来区分这一点
  • 那么你有一个杂乱无章的 API,它返回 400 什么的。无论如何,这个 sn-p 暴露了response,您甚至可以从中读取我相信的正文。在 Rajat Beck 发表评论的地方实现您自己的逻辑。这是一个很好的答案。
猜你喜欢
  • 2018-09-13
  • 2019-11-26
  • 2021-02-16
  • 2019-11-20
  • 2021-10-11
  • 2016-01-26
  • 1970-01-01
  • 2018-06-22
  • 1970-01-01
相关资源
最近更新 更多