阅读 342

网络请求--token

请求中添加token

登录成功后,之后的请求一般都需要将token添加到请求头中,才能得到正确的回调结果。利用Okhttp的Interceptor可以方便的做到这一点

public class TokenInterceptor implements Interceptor {

    private String token;

    public TokenInterceptor(String token) {
        this.token = token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    @Override
    public @NotNull Response intercept(@NotNull Chain chain) throws IOException {
        Request original = chain.request();
        Request.Builder builder = original.newBuilder()
                .header("token", token);
        Request request = builder.build();
        return chain.proceed(request);
    }
}
复制代码

登录成功后:

 TokenInterceptor tokenInterceptor = new TokenInterceptor(token);
        HttpManager.getInstance().addInterper(tokenInterceptor);
复制代码

token失效后的处理

token失效后,可请求新的token后,用新token请求当前数据;或许直接跳转到登录页。 这两种方式都需要在token失效时能拦截到。

方式1:实现Authenticator接口

public class TokenAuthenticator implements Authenticator {
 
    @Override
    public Request authenticate(Proxy proxy, Response response) throws IOException {
 
        //取出本地的refreshToken
        String refreshToken = "sssgr122222222";
 
        // 通过一个特定的接口获取新的token,此处要用到同步的retrofit请求
        ApiService service = ServiceManager.getService(ApiService.class);
        Call<String> call = service.refreshToken(refreshToken);
 
        //要用retrofit的同步方式
        String newToken = call.execute().body();
 
        return response.request().newBuilder()
                .header("token", newToken)
                .build();
    }
 
    @Override
    public Request authenticateProxy(Proxy proxy, Response response) throws IOException {
        return null;
    }
}
复制代码

由于业务中没遇到过这种http响应401的情况,所以只是转载记录一下,大多时遇到方式2的情况,在http响应200的情况下,判断自定义状态码,反馈token失效的情况:

{"data":null,"message":"请重新登录。","status":401}
复制代码
public class TokenInterceptor implements Interceptor {
 
    private static final Charset UTF8 = Charset.forName("UTF-8");
 
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
 
        // try the request
        Response originalResponse = chain.proceed(request);
 
        /**通过如下的办法曲线取到请求完成的数据
         *
         * 原本想通过  originalResponse.body().string()
         * 去取到请求完成的数据,但是一直报错,不知道是okhttp的bug还是操作不当
         *
         * 然后去看了okhttp的源码,找到了这个曲线方法,取到请求完成的数据后,根据特定的判断条件去判断token过期
         */
        ResponseBody responseBody = originalResponse.body();
        BufferedSource source = responseBody.source();
        source.request(Long.MAX_VALUE); // Buffer the entire body.
        Buffer buffer = source.buffer();
        Charset charset = UTF8;
        MediaType contentType = responseBody.contentType();
        if (contentType != null) {
            charset = contentType.charset(UTF8);
        }
 
        String bodyString = buffer.clone().readString(charset);
 
        LogUtil.debug("body---------->" + bodyString);
 
        /***************************************/
 
        if (response shows expired token){//根据和服务端的约定判断token过期
 
            //取出本地的refreshToken
            String refreshToken = "sssgr122222222";
 
            // 通过一个特定的接口获取新的token,此处要用到同步的retrofit请求
            ApiService service = ServiceManager.getService(ApiService.class);
            Call<String> call = service.refreshToken(refreshToken);
 
            //要用retrofit的同步方式
            String newToken = call.execute().body();
 
 
            // create a new request and modify it accordingly using the new token
            Request newRequest = request.newBuilder().header("token", newToken)
                    .build();
 
            // retry the request
 
            originalResponse.body().close();
            return chain.proceed(newRequest);
        }
 
        // otherwise just pass the original response on
        return originalResponse;
    }
}
复制代码
OkHttpClient client = new OkHttpClient();
client.interceptors().add(new TokenInterceptor());
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(BASEURL)
        .addConverterFactory(GsonConverterFactory.create(gson))
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .client(getOkHttpClient())
        .build();
复制代码

引用

Android处理token失效的处理方法

retrofit 刷新token并发处理

Android网络实战篇——Token添加、过期判定以及处理(全局自动刷新)

文章分类
Android
文章标签