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

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

问题描述

我正在使用 Auth0,它给了我一个 JWT(json web 令牌)和一个 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.在这种情况下,我可以要求 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 是否failsucceed,如果 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 上:

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天全站免登陆