retrofit+okhttp+coroutines拦截Token失效(四种解决token失效的方案 )

背景

Token是当前用于客户端到服务端做身份验证的一种较为常见的机制. 客户端先通过用户名、密码登陆服务器,获取token,后续每次请求都带上token.当token在有效期内,服务器都校验通过,失效后,则返回鉴权失败,客户端需要重新登陆获取token. 如果过一段时间就需要用户登陆一次,这显然非常不友好.那怎么办呢?

解决方案

  1. 方案一、token设置为永远有效.
    这显然是下下招,一旦token被人截获,就被人玩死了.
  2. 方案二、app启动就检查token是否将要失效,如果是,则自动登陆刷新token,app运行中,也定时检查并刷新token.
  3. 方案三、每次请求前,都判断token是否将要失效,如果是,则自动登陆刷新token,然后再发出原请求.
  4. 方案四、Token失效拦截. 对所有请求(除登陆请求)进行拦截,如果token失效,则自动登陆刷新token,然后再发出原请求. 本文仅介绍此方案的具体实现方式.

Token失效拦截实现方法

  1. 为okhttp设置拦截器
    其中HttpHeaderInterceptor是为所有请求添加token字段的拦截器;TokenInterceptor是检测token是否失效并重新登陆的拦截器.
OkHttpClient.Builder()
.apply {
    addInterceptor(HttpHeaderInterceptor())
    addInterceptor(TokenInterceptor())
}.build()
  1. token拦截器中,需对返回信息做判断,看是否失效.如果失效,则自动登陆,然后重新执行原请求.注意:自动登陆时,不能再采用coroutines异步执行,必须要用同步方式,才能登陆后执行原请求并返回执行结果给调用者.
class TokenInterceptor : BaseInterceptor() {
    override fun interceptMe(chain: Interceptor.Chain): Response {
        val request = chain.request()
        var response = chain.proceed(request)
        if (isTokenExpired(response)) {
            response = loginAndReSendOriginalRequest(request, response, chain)
        }

        return response
    }

    /**
     * 重新登陆,并再次发送之前的请求
     */
    private fun loginAndReSendOriginalRequest(request: Request, originalResponse: Response,
                                              chain: Interceptor.Chain): Response {
        var response = originalResponse
        LoginManager.login(
                onSuccess = {
                    val newRequest = replaceTokenInHeader(request, it.token)
                    response?.close()
                    response = chain.proceed(newRequest)
                }
        )
        return response
    }

    /**
     * 判断token是否失效。
     * TODO: 下面函数isTokenExpired只是测试样例,固定返回true;应根据实际项目修改。
     */
    private fun isTokenExpired(response: Response) = true//(response.code() == TOKEN_EXPIRED)
}```

# Demo源代码
https://gitee.com/cxyzy1/coroutineRetrofitDemo.git






安卓开发技术分享: https://blog.csdn.net/yinxing2008/article/details/84555061
[点击关注专栏,查看最新技术分享](https://blog.csdn.net/yinxing2008/column/info/34054)
更多技术总结好文,请关注:「程序园中猿」

你可能感兴趣的:(安卓)