美文网首页
OKHttp简单易懂全局自动刷新Token

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

作者: 有没有口罩给我一个 | 来源:发表于2018-03-12 22:10 被阅读0次

    概述

    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<String, String> map = new HashMap<>();
                map.put("refresh_token", refresh_token);
                HttpResult<UserInfoData> 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

          本文链接:https://www.haomeiwen.com/subject/wwiofftx.html