问题
成都创新互联公司专业为企业提供宜城网站建设、宜城做网站、宜城网站设计、宜城网站制作等企业网站建设、网页设计与制作、宜城企业网站模板建站服务,十载宜城做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。
一次面试遇到的一个问题,其实也是实际开发中很容易遇到的问题,特此记录一下。
当请求某个接口的时候,我们会在请求的header中携带token消息,但是发现token失效,接口请求报错,怎么马上刷新token,然后重复请求方才那个接口呢?这个过程应该说对用户来说是无感的。
这个过程用流程图可以这样表示:
自动更新token流程
要实现上述需求的话,大家会如何实现呢?
首先讲一下Token和Cookie吧
- cookie
cookie是保存在本地终端的数据。cookie由服务器生成,发送给浏览器,浏览器把cookie以kv形式保存到某个目录下的文本文件内,下一次请求同一网站时会把该cookie发送给服务器。由于cookie是存在客户端上的,所以浏览器加入了一些限制确保cookie不会被恶意使用,同时不会占据太多磁盘空间,所以每个域的cookie数量是有限的。
cookie的组成有:名称(key)、值(value)、有效域(domain)、路径(域的路径,一般设置为全局:"")、失效时间、安全标志(指定后,cookie只有在使用SSL连接时才发送到服务器(https))。
- token
token的意思是“令牌”,是用户身份的验证方式,最简单的token组成:uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,由token的前几位+盐以哈希算法压缩成一定长的十六进制字符串,可以防止恶意第三方拼接token请求服务器)。还可以把不变的参数也放进token,避免多次查库。
解决方案
自定义自动刷新token的拦截器
import android.util.Log; import java.io.IOException; import okhttp3.Interceptor; import okhttp3.Request; import okhttp3.Response; /** * 自动刷新token的拦截器 * * @author shijiacheng * @version 1.0 */ public class TokenInterceptor implements Interceptor { private static final String TAG = "TokenInterceptor"; @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Response response = chain.proceed(request); Log.d(TAG, "response.code=" + response.code()); //根据和服务端的约定判断token过期 if (isTokenExpired(response)) { Log.d(TAG, "自动刷新Token,然后重新请求数据"); //同步请求方式,获取最新的Token String newToken = getNewToken(); //使用新的Token,创建新的请求 Request newRequest = chain.request() .newBuilder() .header("Authorization", "Basic " + newToken) .build(); //重新请求 return chain.proceed(newRequest); } return response; } /** * 根据Response,判断Token是否失效 * * @param response * @return */ private boolean isTokenExpired(Response response) { if (response.code() == 301) { return true; } return false; } /** * 同步请求方式,获取最新的Token * * @return */ private String getNewToken() throws IOException { // 通过获取token的接口,同步请求接口 String newToken = ""; return newToken; } }
配置下OkHttpUtils
/** * 初始化OkHttpUtils */ public OkHttpUtils(){ /** * 配置OkHttpClient */ OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(15, TimeUnit.SECONDS) .readTimeout(3000, TimeUnit.SECONDS) .writeTimeout(3000, TimeUnit.SECONDS) // .cache(new Cache()) // .addInterceptor(interceptor)//这里可以继续添加多种拦截器 .addInterceptor(new TokenInterceptor())//添加获取token的拦截器 .build(); }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持创新互联。