专栏首页恩蓝脚本Android OkHttp实现全局过期token自动刷新示例

Android OkHttp实现全局过期token自动刷新示例

问题

一次面试遇到的一个问题,其实也是实际开发中很容易遇到的问题,特此记录一下。

当请求某个接口的时候,我们会在请求的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,避免多次查库。

解决方案

  1. 通过拦截器,获取返回的数据
  2. 判断token是否过期
  3. 如果token过期则刷新token
  4. 使用最新的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();
  
}

以上就是本文的全部内容,希望对大家的学习有所帮助。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Laravel (Lumen) 解决JWT-Auth刷新token的问题

    Laravel(Lumen)中使用JWT-Auth遇到一个问题,即token如何刷新。

    砸漏
  • laravel5.5安装jwt-auth 生成token令牌的示例

    ‘Tymon\JWTAuth\Providers\JWTAuthServiceProvider’,

    砸漏
  • thinkphp5框架API token身份验证功能示例

    本文实例讲述了thinkphp5框架API token身份验证功能。分享给大家供大家参考,具体如下:

    砸漏
  • Vue + Flask 小知识(六)

    由于我们会有很多请求,都需要验证 token 的有效性,那么把这部分逻辑抽象出来就是最好的选择了。我这里大概想到了以下两种验证的方法

    周萝卜
  • vue- axios设置全局请求头

    一般在前后端分离的情况下,后台提供的restful接口,为了确保接口的安全性。必须设置一些相关的安全认证,这里是对如何使用tokne进行安全验证的设置

    java攻城狮
  • 基于Flask开发企业级REST API应用(三)

    前两章把程序的结构以及 API的协议基本上搭建起来了。本文开始不打算对每个模块接口都进行实现,因为基本上都是业务逻辑代码,而且整篇文章都把代码贴出来,那将是一个...

    阳仔
  • 【thinkphp】app接口签名+验证签名

    【thinkphp】app接口签名+验证签名 app接口签名+验证签名 比较简单 求各位大牛指教 IndexController.class.php <?php...

    96php.cn
  • OAuth2.0实战案例(四)搭建认证服务,简化模式测试

    现在在浏览器数据的地址就变为了 http://localhost:9001/oauth/authorize?response_type=token&clien...

    一天不写程序难受
  • laravel5.5安装jwt-auth 生成token令牌的示例

    ‘Tymon\JWTAuth\Providers\JWTAuthServiceProvider’,

    砸漏
  • Laravel (Lumen) 解决JWT-Auth刷新token的问题

    Laravel(Lumen)中使用JWT-Auth遇到一个问题,即token如何刷新。

    砸漏

扫码关注云+社区

领取腾讯云代金券