Android Token过期解决方案

来源:互联网 发布:淘宝商品名称 编辑:程序博客网 时间:2024/05/20 11:26

对开发中遇到的问题进行整理记录~~


场景:Token验证较多的Android应用;


需求:在Token过期后,向服务器重新获取Token并使用新Token重新发起请求;


实现: 参考:http://www.jianshu.com/p/62ab11ddacc8

1、服务器若能在Token过期时返回401错误码,则可以使用OkHttp提供的Authenticator接口(未验证);

2、实现OkHttp的Interceptor接口,并使用同步的Retrofit请求


public class TokenInterceptor implements Interceptor {    @ParametersAreNonnullByDefault    @Override    public Response intercept(Chain chain) throws IOException {        Request request = chain.request();        Response originalResponse = chain.proceed(request);        String url = request.url().toString();//请求Url        //获取返回的json,response.body().string();只有效一次,对返回数据进行转换        ResponseBody responseBody = originalResponse.body();        BufferedSource source = responseBody.source();        source.request(Long.MAX_VALUE); // Buffer the entire body.        Buffer buffer = source.buffer();        Charset charset = Charset.forName("UTF-8");        MediaType contentType = responseBody.contentType();        if (contentType != null) {            charset = contentType.charset(Charset.forName("UTF-8"));        }        String bodyString = buffer.clone().readString(charset);//首次请求返回的结果        if (isTokenExpired(bodyString)) {//根据和服务端的约定判断token过期            //同步请求方式,获取最新的Token            TokenEntity tokenEntity = getNewToken();            //使用新的Token,创建新的请求            if(request.body() instanceof FormBody){                FormBody.Builder newFormBody = new FormBody.Builder();                FormBody oidFormBody = (FormBody) request.body();                for (int i = 0;i<oidFormBody.size();i++){                    //根据需求修改参数                    if ("需要更新的token参数字段".equals(oidFormBody.encodedName(i))) {                        newFormBody.addEncoded(oidFormBody.encodedName(i),tokenEntity.getToken());                    }else {                        newFormBody.addEncoded(oidFormBody.encodedName(i),oidFormBody.encodedValue(i));                    }                }                Request.Builder builder = request.newBuilder();                builder.url(url);                builder.method(request.method(),newFormBody.build());                request = builder.build();            }            originalResponse.body().close();            //重新请求            return chain.proceed(request);        }        return originalResponse;    }    /**     * 根据Response约定,判断Token是否失效     * @param response     */    private boolean isTokenExpired(String response) {        JSONObject obj = null;        try {            obj = new JSONObject(response);            if ("Token过期的判断条件") {                return true;            }        } catch (JSONException e) {            e.printStackTrace();        }        return false;    }    /**     * 同步请求方式,获取最新的Token     */    private LoginEntity getNewToken() throws IOException {        // 通过一个特定的接口获取新的token,此处要用到同步的retrofit请求        Call<LoginEntity> loginCall = RetrofitHelper.getInstance().getRetrofit(Api.class)                .getToken("参数");        return loginCall.execute().body();    }
然后在OkHttp中配置

okHttpClient = new OkHttpClient.Builder()        .connectTimeout(10, TimeUnit.SECONDS)//连接超时        .readTimeout(15, TimeUnit.SECONDS)//读取超时        .writeTimeout(15, TimeUnit.SECONDS)//写入超时        .addInterceptor(new TokenInterceptor())//okhttp拦截器 Application拦截        .build();

原创粉丝点击