美文网首页
一次Token拦截更换

一次Token拦截更换

作者: Leero丶 | 来源:发表于2019-03-19 11:19 被阅读0次

因为业务扩展,需要对接第三方公司的服务器接口,然后呢这接口对接的时候还挺好玩的,所以记录一下。
根据对方的接口文档:所有接口返回都是统一 MsgCode + Msg + 其他 的形式。然后登录后Token的有效时间为10分钟,但是从业务流程来看这10分钟啥也干不了😊

行吧,反正用的是OKHttp,写个拦截器呗......
然后实现和一般的Token拦截差不多,只是Token并不是放在header,需要放在请求体中。
1.第一次请求后获取返回数据,判断MsgCode状态码
2.当判断为Token失效的时候,同步请求登录接口获取新的Token
3.更换请求参数中的Token,再次请求数据接口

思路就是这样的,先上代码再吐槽......

class TokenInterceptor : Interceptor {

    override fun intercept(chain: Interceptor.Chain): Response {
        val request: Request = chain.request()

        val originalResponse: Response = chain.proceed(request)
        val responseBody: ResponseBody? = originalResponse.body()
        val source: BufferedSource? = responseBody?.source()
        source?.request(Long.MAX_VALUE)
        val buffer: Buffer? = source?.buffer()
        val contentType: MediaType? = responseBody?.contentType()
        val charset = contentType?.charset(Charsets.UTF_8)

        val bodyString: String = buffer?.clone()?.readString(charset) ?: "{}"
        Log.d("onResponse", bodyString)
        Log.d("onResponse", "----------------------------------")

        val jsonObject = JSONObject(bodyString)
        // token 过期
        if ((jsonObject.has("MsgCode") && ("00002" == jsonObject.getString("MsgCode")))) {
            val map = HashMap<String, Any>()
            map["UserID"] = Constant.USER_NAME
            map["PassWord"] = Constant.ACCOUNT_PASSWORD

            val service: Apis = HttpClient.create(Apis::class.java)
            val call: Call<TokenBean> = service.getToken(Gson().toJson(map))
            // 同步获取新token,再次请求接口
            val resultBean: TokenBean? = call.execute().body()
            Log.d("onResponse", "new Token --- ${resultBean!!.userToken}")
            SPUtils.putString(Constant.USER_TOKEN, resultBean.userToken)

            // 获取请求参数,更换token
            val body = request.body()
            val buffer = Buffer()
            body?.writeTo(buffer)

            var parameterStr = buffer.readUtf8()
            Log.d("111", "请求参数---$parameterStr")
            parameterStr = URLDecoder.decode(parameterStr, "UTF-8")
            Log.d("111", "解析后的请求参数---${parameterStr.substring(1)}")
            val jsonObject = JSONObject(parameterStr.substring(1))
            val newMap = HashMap<String, Any>()
            val iterator = jsonObject.keys()
            while (iterator.hasNext()) {
                val key = iterator.next()
                if ("Token" == key) {
                    newMap[key] = resultBean.userToken
                } else {
                    newMap[key] = jsonObject.getString(key)
                }
            }
            Log.d("111", "新的请求参数" + Gson().toJson(newMap))
            val requestBody =
                RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"), "=${Gson().toJson(newMap)}")
            val newRequest: Request = request.newBuilder().post(requestBody).build()
            originalResponse.body()?.close()

            return chain.proceed(newRequest)
        }

        return originalResponse
    }
}
  1. 请求的表单数据编码Content-Type 指定为 application/x-www-form-urlencoded,这完全不是问题撒,可是我就是怎么提交都不行!为什么!!关键还不好意思去问,不然别人觉得我连提交个表单数据都不会,还是要点面子的:)然后各种测试,终于通了:)表单里键值对就一个,key是空字符串,然后所有的参数是json字符串放在value中:)nice啊老哥,这种特殊的点就不能交代一哈吗:)
  2. 按照文档写的去请求数据,居然给我返回消息缺少必要参数 :)
  3. 接口返回的数据居然不是按照接口文档写的那样?!wo diu 这么随意的吗?

相关文章

网友评论

      本文标题:一次Token拦截更换

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