微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在不添加特定代码的情况下处理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();
             }
         }
    )

原文地址:https://www.jb51.cc/android/317126.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐