如何在不添加特定代码的情况下处理auth0 403错误(Retrofit/okhttp/RxAndroid) [英] How to handle auth0 403 error without adding specific code everywhere (Retrofit/okhttp/RxAndroid)

查看:213
本文介绍了如何在不添加特定代码的情况下处理auth0 403错误(Retrofit/okhttp/RxAndroid)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Auth0,这给了我一个JWT(json网络令牌)和一个refreshtoken.我在http标头中使用此JWT与后端通信.

I am using Auth0, which gives me a JWT (json web token) and a refreshtoken. I use this JWT in the http headers to communicate with my backend.

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

It could happen, that the server gives me a 403, when it decides that the JWT has expired. In this event, I can ask Auth0 to issue me a new JWT, using the refreshtoken. It means I call the Auth0 backend, pass it the refreshtoken, and it gives me a new JWT, which I can then use in my requests.

我的问题是,如何在所有网络代码中有效地编写此行为?我将要与几个端点进行对话,它们都可能返回403.

My question is, how can I efficiently write this behaviour in all my networking code? I will have a couple of endpoints to talk to, and they all might return the 403.

我想我应该先创建一个将JWT添加到所有请求的拦截器.

I am thinking I should first make an interceptor that adds the JWT to all requests.

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

Then there should be behaviour that detects the 403, quietly does a networkcall to Auth0, retrieving the new JWT. Then the original request should be tried again, with the new JWT in its headers.

因此,我宁愿让此403处理其他代码看不见的地方,而且绝对不必在任何地方重写它.

So I would prefer to have this 403 handling somewhere invisible to my other code, and definitely not have to rewrite it everywhere.

任何有关如何实现这一目标的指针将不胜感激.

Any pointers on how to achieve this will be appreciated.

-

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

To be clear, I am basically looking for pointers on how to achieve this using RxAndroid Observables. When a certain Observable finds the 403, it should 'inject' a new network call.

推荐答案

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

I solved this issue by writing an Interceptor for OkHttp. It checks the statuscode of the network call. If it's a 403, call Auth0 servers and request a new id_token. Then use this token in a new version of the original request.

为了进行测试,我编写了一个小型网络服务器,用于检查 TestHeader 是否为失败成功,如果 fail则返回403 .

To test, I wrote a little webserver that checks the TestHeader for fail or succeed and returns a 403 if it's fail.

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;
        }
    }
}

然后,将此拦截器附加到OkHttpClient上,然后将其插入到Retrofit适配器中:

Then I attach this Interceptor to an OkHttpClient which I plug into the Retrofit adapter:

// 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();
             }
         }
    )

这篇关于如何在不添加特定代码的情况下处理auth0 403错误(Retrofit/okhttp/RxAndroid)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆