OKHttp简单易懂全局自动刷新Token

概述

Android端登陆接口获取一个token 和一个刷新token用的refresh_token,
在接下来的token请求中,所有的接口都需要携带token请求,以便服务端来验证请求的来源是合法的,token的作用是避免频繁请求造成服务压力。而token是具有时效性的,服务端会给他一个时效性,这个时效性有服务器定;如果token是有效的,可以请求成功,而过了这个时间段,这个token就失效了。这时候需要我们使用refresh_token 请求刷新token的接口来获取新的token 和 refresh_token,这样就可以源源不断的保持我们持有的token是有效合法的

设计思想

那么token失效,请求接口失败,那我们该怎么在请求接口请求失败时,请求刷新token之后再重新请求呢,如果按照?这里我会使用OKHttp,相信大家都在使用OKHttp吧?那一定知道OKHttp有Interceptor 拦截器,我的思路是在Interceptor 中拿到响应数据,在根据数据贩毒案token是否失效,如果失效则自动刷新token在重新请求。
我把部分代码亮出来:

      Request originalRequest = chain.request();
    if (originalRequest.method().equals("POST")) {
        Response response = chain.proceed(originalRequest);
        if (isTokenExpired(response)) {
            FormBody originalFormBody = (FormBody) originalRequest.body();
            FormBody.Builder newBuilder = new FormBody.Builder();
            for (int i = 0; i < originalFormBody.size(); i++) {
                newBuilder.add(originalFormBody.name(i), originalFormBody.value(i));
            }
            //获取本地refresh_token
            String refresh_token = SPUtil.getString(Constants.userinfo.refresh_token, Constants.net.DEFAULT_REFRESH_TOKEN);
            HashMap map = new HashMap<>();
            map.put("refresh_token", refresh_token);
            HttpResult httpResult = new APIFactory(mContext)
                    .refrashToken(map)
                    .execute().body();

            /**
             *如果刷新refresh_token失败,则默认为登陆失效,需要重新登陆
             */
            if (httpResult.code != Constants.net.SUCCESS)
                throw new APIException(httpResult.code, httpResult.message);

            String access_token = httpResult.payload.getResult().getAccess_token();
            SPUtil.getString(Constants.userinfo.access_token, access_token);
            SPUtil.getString(Constants.userinfo.refresh_token, httpResult.payload.getResult().getRefresh_token());

            //添加新token,重新请求
            newBuilder.add("token", access_token);
            Request newRequest = originalRequest.newBuilder()
                    .method(originalRequest.method(), newBuilder.build())
                    .build();
            return chain.proceed(newRequest);//重新请求
        }
        return response;
    }
    return chain.proceed(originalRequest);

 private boolean isTokenExpired(Response response) {
    try {
        if (response.isSuccessful()) {
            ResponseBody responseBody = response.body();
            BufferedSource source = responseBody.source();
            source.request(Long.MAX_VALUE);
            Buffer buffer = source.buffer();
            Charset charset = UTF8;
            MediaType contentType = responseBody.contentType();
            if (contentType != null) {
                charset = contentType.charset(UTF8);
            }
            String bodyString = buffer.clone().readString(charset);
            HttpResult httpResult = new Gson().fromJson(bodyString, HttpResult.class);
            return httpResult.code == Constants.net.LOCAL_TOKEN_INVALID;
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return response.code() == Constants.net.LOCAL_TOKEN_INVALID;
}

代码有注释就不解释了,这里需要注意的是:本来想response.body().string()有坑,当使用该方法那么流会被关闭,在使用就会抛异常。

你可能感兴趣的:(OKHttp简单易懂全局自动刷新Token)