如何在okhttp3身份验证器中使用具有异步请求的刷新令牌添加身份验证

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在okhttp3身份验证器中使用具有异步请求的刷新令牌添加身份验证相关的知识,希望对你有一定的参考价值。

我有一个连接到Okhttp3客户端的身份验证器,当401响应响起时,该客户端被成功调用。在身份验证器中,我想使用刷新令牌对用户进行身份验证。我正在使用IBM AppId进行身份验证。

private Authenticator getAuthenticator() 
        return new Authenticator() 

            @Override
            public Request authenticate(Route route, Response response) throws IOException 
                // code to authenticate with refresh token 
                return null;
            
        ;
    

我有以下代码用刷新令牌进行身份验证:

AppID.getInstance().signinWithRefreshToken(getApplicationContext(), refreshTokenString, new AuthorizationListener() 
    @Override
    public void onAuthorizationFailure(AuthorizationException exception) 
        //Exception occurred
    

    @Override
    public void onAuthorizationCanceled() 
        //Authentication canceled by the user
    

    @Override
    public void onAuthorizationSuccess(AccessToken accessToken, IdentityToken identityToken, RefreshToken refreshToken) 
        //User authenticated
    
);

现在您可以看到它是异步请求,我无法将此代码放在验证器中,因为该方法将在调用onAuthorizationSuccess()之前返回。此外,AppId没有我可以使用的同步类型的请求。能不能指出我如何在authenticator类中使用这段代码。请帮我解决这个问题。

答案

我有一个解决方案。请尝试下面的代码。

使类如:TokenAuthenticator.java

import android.content.Context;
import android.support.annotation.Nullable;

import com.dmlllc.insideride.common.Preferences;
import com.dmlllc.insideride.model.AccessToken;
import com.dmlllc.insideride.restModel.RestResponse;
import com.dmlllc.insideride.restModel.requestModel.AccessTokenReq;

import java.io.IOException;

import okhttp3.Authenticator;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.Route;

public class TokenAuthenticator implements Authenticator 

    private Context context;

    public TokenAuthenticator(Context context) 
        this.context = context;
    

    @Nullable
        @Override
        public Request authenticate(Route route, Response response) throws IOException 
            // Refresh your access_token using a synchronous api request
            AccessTokenReq accessTokenReq = new AccessTokenReq(Preferences.getPreferenceString(context, Preferences.USERNAME_FOR_TOKEN, ""),
                    Preferences.getPreferenceString(context, Preferences.PASSWORD_FOR_TOKEN, ""));
            try 
                retrofit2.Response<RestResponse<AccessToken>> tokenResponse = Global.initRetrofit(context).getAccessToken(accessTokenReq).execute();
                if (tokenResponse.body() != null) 
                    if (tokenResponse.body().getResStatus().equals("success")) 
                        SessionManager sessionManager = new SessionManager(context);
                        sessionManager.storeToken(tokenResponse.body().getResults().getYourAccessToken());
                        Preferences.setPreferenceString(context, Preferences.ACCESS_TOKEN, tokenResponse.body().getResults().getYourAccessToken());
                    
                
            catch (Exception e)
                e.printStackTrace();
            

            // Add new header to rejected request and retry it
            return response.request().newBuilder()
                    .header("Authorization", Preferences.getPreferenceString(context, Preferences.ACCESS_TOKEN, ""))
                    .build();
        
    

然后在您的改造方法中使用此类,如:

public static RestApi initRetrofit(Context context) 
        // For logging request & response (Optional)
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        TokenAuthenticator tokenAuthenticator = new TokenAuthenticator(context);

        OkHttpClient client = new OkHttpClient.Builder()
                .authenticator(tokenAuthenticator)
                .addInterceptor(loggingInterceptor)
                .connectTimeout(1, TimeUnit.MINUTES)
                .writeTimeout(1, TimeUnit.MINUTES)
                .readTimeout(1, TimeUnit.MINUTES)
                .build();

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(URL.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build();
        return retrofit.create(RestApi.class);
    

希望它也会帮助你。 :)快乐编码...... !!!

另一答案

我有两个可能让您感兴趣的解决方案:

  1. 自己打电话给API。这可能很难,但你也可以浏览AppId SDK寻求帮助。
  2. 使用同步signinWithRefreshToken()调用fork并修改AppId SDK并使用它。另外,请确保在原始仓库中创建功能请求或提取有关此更改的请求,因此这可能包含在下一版本中。 这样做的缺点是你必须维护AppId SDK的另一个分支,并在需要时加时合并新的变更。

以上是关于如何在okhttp3身份验证器中使用具有异步请求的刷新令牌添加身份验证的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 云功能,具有对外部 api 的基本身份验证的获取请求

如何在身份服务器 4/身份验证代码流中请求访问令牌的附加声明?

请求具有无效的身份验证凭据。预期的 OAuth 2 访问令牌、登录 cookie 或其他有效的身份验证凭据 automl

它是不是需要在任何具有基本身份验证的请求中传递用户名:密码组合?

如何在 api 调用中使用异步等待获取在反应本机中通过基本身份验证

具有摘要身份验证的 HttpClient 发布请求导致错误请求