如何在不添加特定代码的情况下处理auth0 403错误(Retrofit / okhttp / RxAndroid)

前端之家收集整理的这篇文章主要介绍了如何在不添加特定代码的情况下处理auth0 403错误(Retrofit / okhttp / RxAndroid)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用Auth0,它给了我一个JWT(json web令牌)和一个refreshtoken.我在http标头中使用此JWT与我的后端进行通信.

当它确定JWT已经过期时,服务器可能会给我一个403.在这种情况下,我可以让Auth0使用refreshtoken向我发出一个新的JWT.这意味着我调用Auth0后端,将其传递给refreshtoken,它给了我一个新的JWT,然后我可以在我的请求中使用它.

我的问题是,如何在我的所有网络代码中有效地编写此行为?我将有几个端点可以交谈,他们都可以返回403.

我想我应该首先制作一个拦截器,将JWT添加到所有请求中.

然后应该有检测403的行为,静静地对Auth0进行网络调用,检索新的JWT.然后应该再次尝试原始请求,并在其标题添加新的JWT.

所以我更喜欢将403处理到我的其他代码看不到的地方,并且绝对不必在任何地方重写它.

任何关于如何实现这一点的指示将不胜感激.

要清楚,我基本上是在寻找如何使用RxAndroid Observables实现这一目标的指针.当某个Observable找到403时,它应该“注入”一个新的网络呼叫.

解决方法

我通过为OkHttp编写一个Interceptor来解决这个问题.它检查网络呼叫的状态代码.如果是403,请调用Auth0服务器并请求新的id_token.然后在原始请求的新版本中使用此令牌.

为了测试,我编写了一个小的Web服务器来检查TestHeader是否失败或成功,如果失败则返回403.

public class AuthenticationInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request originalRequest = chain.request();
        Request authenticationRequest = originalRequest.newBuilder()
                .header("TestHeader","fail")
                .build();

        Response origResponse = chain.proceed(authenticationRequest);

        // server should give us a 403,since the header contains 'fail'
        if (origResponse.code() == 403) {
            String refreshToken = "abcd"; // you got this from Auth0 when logging in

            // start a new synchronous network call to Auth0
            String newIdToken = fetchNewIdTokenFromAuth0(refreshToken);

            // make a new request with the new id token
            Request newAuthenticationRequest = originalRequest.newBuilder()
                    .header("TestHeader","succeed")
                    .build();

            // try again
            Response newResponse = chain.proceed(newAuthenticationRequest);

            // hopefully we now have a status of 200
            return newResponse;
        } else {
            return origResponse;
        }
    }
}

然后我将这个Interceptor附加到一个OkHttpClient,我将其插入Retrofit适配器:

// add the interceptor to an OkHttpClient

public static OkHttpClient getAuthenticatingHttpClient() {
    if (sAuthenticatingHttpClient == null) {
        sAuthenticatingHttpClient = new OkHttpClient();
        sAuthenticatingHttpClient.interceptors().add(new AuthenticationInterceptor());
    }
    return sAuthenticatingHttpClient;
}

// use the OkHttpClient in a Retrofit adapter

mTestRestAdapter = new RestAdapter.Builder()
    .setClient(new OkClient(Network.getAuthenticatingHttpClient()))
    .setEndpoint("http://ip_of_server:port")
    .setLogLevel(RestAdapter.LogLevel.FULL)
    .build();

// call the Retrofit method on buttonclick

ViewObservable.clicks(testNetworkButton)
    .map(new Func1<OnClickEvent,Object>() {
             @Override
             public Object call(OnClickEvent onClickEvent) {
                 return mTestRestAdapter.fetchTestResponse();
             }
         }
    )

猜你在找的Android相关文章