美文网首页工作生活
Retrofit中Token过期处理

Retrofit中Token过期处理

作者: 烂吹笙 | 来源:发表于2019-06-29 16:39 被阅读0次

    Android中使用Retrofit刷新Token

    实际开发中,例如登录,我们向后台传参用户名和密码,后台会返回给我们一个Token,用于后面接口的调用,
    这样后端就能通过我们传入的token知道我们是哪个用户,一般token的有效期是2小时。2小时候token会自动过期。我们需要拿到新的Token,保持登陆状态。

    如何刷新Token呢

    刷新Token流程图.png

    如上图所示,我们loging过后后台返回token、refreshToken给客户端,token有效时长2小时,而refreshToken时间较长有15天,2小时候我们调用接口,后端告诉我们token过期,那我们拿之前存的refreshToken去调用刷新Token的接口,后端会从新给我一个新的token和refreshToken,依次类推,我们就能实现长期登录,除非用户15天不登录,refreshToken过期。

    • 示例代码
    
    public class TokenInterceptor implements Interceptor {
    
        @Override
        public Response intercept(Chain chain) throws IOException {
    
            Request originalRequest = chain.request();
            Response response = chain.proceed(originalRequest);
    
            try {
                ResponseBody responseBody = response.body();
                //解决response.body().string();只能打印一次
                BufferedSource source = responseBody.source();
                source.request(Long.MAX_VALUE); // Buffer the entire body.
                Buffer buffer = source.buffer();
                Charset UTF8 = Charset.forName("UTF-8");
                String string = buffer.clone().readString(UTF8);
    
                BaseResponseBean baseResponseBean = new Gson().fromJson(string, BaseResponseBean.class);
                if (baseResponseBean != null) {
                    if (baseResponseBean.getCode().equals(ResponseCode.TOKEN_ERROR)) {
                        //token过期
                        //根据RefreshToken同步请求,获取最新的Token
                        String newToken = getNewToken();
    
                        //使用新的Token,创建新的请求
                        Request newRequest = chain.request()
                                .newBuilder()
                                .header("authToken", newToken)
                                .build();
                        //重新请求
                        return chain.proceed(newRequest);
                    } else if (baseResponseBean.getCode().equals(ResponseCode.REFRESH_TOKEN_ERROR)) {
                        //refreshToken过期
                        EventBus.getDefault().post(new Handler(Looper.getMainLooper()).obtainMessage(Constants
                                .Key_EventBus_Msg.EVENT_TOKEN_OVERDUE));
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return response;
        }
    
    
        /**
         * 同步请求方式,根据RefreshToken获取最新的Token
         *
         * @return
         */
        private synchronized String getNewToken() throws IOException {
    //        通过一个特定的接口获取新的token,此处要用到同步的retrofit请求
            String newToken = "";
            String paramsRefresh = "";
    
            TokenInfoBean oldTokenBean = TokenInfoBean.readToken();
            if (oldTokenBean != null && !BaseUtils.isEmpty(oldTokenBean.getRefreshToken())) {
                paramsRefresh = oldTokenBean.getRefreshToken();
            }
    
            ApiService apiService = ApiRetrofit.create(ApiService.class);
            RequestBody requestBody = RequestBody.create(MediaType.parse(ContentTypeConstant.Content_TYPE_JSON), "");
            Call<BaseResponseBean<TokenInfoBean>> call = apiService.refreshToken(paramsRefresh, requestBody);
            BaseResponseBean<TokenInfoBean> responseBean = call.execute().body();
            if (responseBean != null && responseBean.getCode().equals(ResponseCode.RESPONSE_SUCCES)
                    && responseBean.getData() != null && !BaseUtils.isEmpty(responseBean.getData().getToken())) {
                //获取新的token成功
                TokenInfoBean infoBean = responseBean.getData();
                TokenInfoBean.saveToken(infoBean);
                newToken = infoBean.getToken();
            }
            return newToken;
        }
    }
    
    

    相关文章

      网友评论

        本文标题:Retrofit中Token过期处理

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