package com.hdl.linkpm.sdk.core.interceptor; import android.text.TextUtils; import android.util.Log; import androidx.annotation.NonNull; import com.google.gson.Gson; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.reflect.TypeToken; import com.hdl.hdlhttp.HxHttpConfig; import com.hdl.linkpm.sdk.core.api.HDLCloudUserApi; import com.hdl.linkpm.sdk.core.code.HDLCloudCode; import com.hdl.linkpm.sdk.core.response.BaseInfo; import com.hdl.linkpm.sdk.user.HDLLinkPMUser; import com.hdl.linkpm.sdk.user.bean.HDLLoginBean; import com.hdl.linkpm.sdk.utils.HDLGsonUtils; import java.io.IOException; import java.nio.charset.Charset; import okhttp3.Headers; import okhttp3.Interceptor; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; import okhttp3.ResponseBody; import okio.Buffer; import okio.BufferedSource; /** * Created by Tong on 2021/11/2. */ public class HDLLoginInterceptor implements Interceptor { @NonNull @Override public Response intercept(@NonNull Chain chain) throws IOException { Request request = chain.request(); if (!isRefreshTokenHeader(request.headers())) { String token = HDLLinkPMUser.getInstance().getAccessToken(); if (!TextUtils.isEmpty(token)) { Request processRequest = addToken(request, token); Response processResponse = chain.proceed(processRequest); return disposeToken(chain, processRequest, processResponse); } } return chain.proceed(request); } @NonNull private Response disposeToken(Chain chain, Request request, Response response) { try { // ResponseBody responseBody2 = response.body(); // BufferedSource source2 = responseBody2.source(); // source2.request(Long.MAX_VALUE); // Buffer buffer2 = source2.getBuffer().clone(); // String respString2 = buffer2.readString(Charset.defaultCharset()); //http标准状态码 if (401 == response.code() || 402 == response.code() || 403 == response.code()) { final String token = refreshToken(); if (!TextUtils.isEmpty(token)) { return chain.proceed(addToken(request, token)); } } else if (response.isSuccessful()) { ResponseBody responseBody = response.body(); if (responseBody != null) { BufferedSource source = responseBody.source(); source.request(Long.MAX_VALUE); Buffer buffer = source.getBuffer().clone(); String respString = buffer.readString(Charset.defaultCharset()); JsonObject object = JsonParser.parseString(respString).getAsJsonObject(); int code = object.get("code").getAsInt(); //1.判断token是否过期是否需要刷新token if (isTokenTimeoutByCode(code)) { final String token = refreshToken(); if (!TextUtils.isEmpty(token)) { return chain.proceed(addToken(request, token)); } } //2.判断Token是否错误 发送登出处理通知 if (isTokenNeedReLoginByCode(code)) { //3.清空登录信息并发出重新登录通知 HDLLinkPMUser.getInstance().logout(0); } } } } catch (Exception e) { Log.d("HDL===>", "disposeToken: 失败," + e); } return response; } /** * 根据code判断token是否失效 需要刷新重新token * * @param code 业务code * @return ture 失效 */ private boolean isTokenTimeoutByCode(int code) { return HDLCloudCode.TOKEN_TIMEOUT == code; } /** * 根据code判断token是否失效 需要重新登录的 * * @param code 业务code * @return ture 失效 */ private boolean isTokenNeedReLoginByCode(int code) { return HDLCloudCode.RE_LOGIN == code || HDLCloudCode.TOKEN_NOT_STANDARD == code || HDLCloudCode.NO_TOKEN == code || HDLCloudCode.CODE_TOKEN_ERROR_10006 == code || HDLCloudCode.CODE_TOKEN_ERROR_10009 == code; } /** * 是否存在刷新头 */ private boolean isRefreshTokenHeader(Headers headers) { String signHeader = headers.get(HDLSmartHeader.REFRESH_TOKEN_HEADER); return !TextUtils.isEmpty(signHeader); } private Request addToken(Request request, String token) { return request.newBuilder() .removeHeader("Authorization") .build() .newBuilder() .method(request.method(), request.body()) .addHeader("Authorization", token) .build(); } /** * 拦截器EncryptInterceptor会处理加密 * * @return token */ private String refreshToken() { final String cacheRefreshToken = HDLLinkPMUser.getInstance().getRefreshToken(); final String regionUrl = HDLCloudUserApi.getRequestUrl(HDLCloudUserApi.POST_LOGIN); final OkHttpClient client = HxHttpConfig.getInstance().getClient(); Request.Builder builder = new Request.Builder(); final JsonObject json = new JsonObject(); json.addProperty("refreshToken", cacheRefreshToken); json.addProperty("grantType", "refresh_token"); final RequestBody requestBody = RequestBody.create(json.toString(), MediaType.parse("application/json;charset=UTF-8")); builder.post(requestBody); builder.url(regionUrl); builder.addHeader(HDLSmartHeader.REFRESH_TOKEN_HEADER, "0"); try { Response response = client.newCall(builder.build()).execute(); if (response.isSuccessful()) { ResponseBody responseBody = response.body(); if (responseBody != null) { BufferedSource source = responseBody.source(); source.request(Long.MAX_VALUE); Buffer buffer = source.getBuffer().clone(); String respString = buffer.readString(Charset.defaultCharset()); BaseInfo baseInfo = HDLGsonUtils.fromJson(respString, new TypeToken>() { }.getType()); if (baseInfo != null) { if (baseInfo.getCode() == HDLCloudCode.SUCCEED) { if (baseInfo.getData() != null) { HDLLoginBean loginBean = baseInfo.getData(); HDLLinkPMUser.getInstance().updateRefreshToken(loginBean); return loginBean.getHeaderPrefix() + loginBean.getAccessToken(); } } else { //refreshToken也过期的话,则发出登出处理通知,重新登录 //清空登录信息并发出重新登录通知 HDLLinkPMUser.getInstance().logout(0); } } } } } catch (Exception ignored) { Log.d("HDL===>", "refreshToken: 失败"); } return ""; } }