package com.hdl.sdk.connect.cloud.interceptor; import android.content.Intent; import android.text.TextUtils; import android.util.Log; import androidx.annotation.NonNull; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.hdl.hdlhttp.HxHttpConfig; import com.hdl.sdk.common.utils.SPUtils; import com.hdl.sdk.connect.cloud.CloudCode; import com.hdl.sdk.connect.cloud.HdlCloudApi; import com.hdl.sdk.connect.cloud.broadcast.CloudBroadcast; import com.hdl.sdk.connect.cloud.broadcast.CloudBroadcastAction; import com.hdl.sdk.connect.config.HDLCloudConfig; import com.hdl.sdk.sourceos.utils.SPKey; 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 = HDLCloudConfig.getInstance().getToken(); if (!TextUtils.isEmpty(token)) { Request processRequest = addToken(request, token); Response processResponse = chain.proceed(processRequest); return disposeToken(chain, processRequest, processResponse); } else { //没有缓存token处理 Response response = chain.proceed(request); //是否需要token,需要则广播 ResponseBody responseBody = response.body(); if (401 == response.code() || 402 == response.code() || 403 == response.code()) { //网络校验异常,需要token final Intent intent = new Intent(); intent.setAction(CloudBroadcastAction.REFRESH_TOKEN_INVALID_ACTION); sendBroadcast(intent); } else if (responseBody != null && response.isSuccessful()) { try { MediaType mediaType = responseBody.contentType(); if (mediaType != null) { String type = mediaType.toString(); //json类型才处理 if (!TextUtils.isEmpty(type) && type.contains("json")) { 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(); if (isTokenLoseByCode(code)) { //token失效了,需要token final Intent intent = new Intent(); intent.setAction(CloudBroadcastAction.REFRESH_TOKEN_INVALID_ACTION); sendBroadcast(intent); } } } } catch (Exception e) { e.printStackTrace(); } } return response; } } return chain.proceed(request); } @NonNull private Response disposeToken(Chain chain, Request request, Response response) { try { if (401 == response.code() || 402 == response.code() || 403 == response.code()) { final String token = refreshToken(); if (!TextUtils.isEmpty(token)) { return chain.proceed(addToken(request, token)); } //网络异常不需要重置token } else if (response.isSuccessful()) { ResponseBody responseBody = response.body(); if (responseBody != null) { MediaType mediaType = responseBody.contentType(); if (mediaType != null) { String type = mediaType.toString(); //json类型才处理 if (!TextUtils.isEmpty(type) && type.contains("json")) { 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 = -1; try { if (object != null) { code = object.get("code").getAsInt(); } } catch (Exception e) { e.printStackTrace(); } String message = ""; try { if (object != null && object.has("message")) { message = object.get("message").getAsString(); if (TextUtils.isEmpty(message)) { message = ""; } } } catch (Exception e) { e.printStackTrace(); } if (isTokenLoseByCode(code)) { //刷新token final String token = refreshToken(); if (!TextUtils.isEmpty(token)) { Response newResponse = chain.proceed(addToken(request, token)); //token更新了 final Intent intent = new Intent(); intent.setAction(CloudBroadcastAction.REFRESH_TOKEN_ACTION); sendBroadcast(intent); return newResponse; } else { //清空token HDLCloudConfig.getInstance().setToken(""); HDLCloudConfig.getInstance().setRefreshToken(""); //token刷新失败,通知token失效了 final Intent intent = new Intent(); intent.setAction(CloudBroadcastAction.REFRESH_TOKEN_INVALID_ACTION); sendBroadcast(intent); } } else { try { //其他异常情况 final Intent intent = new Intent(); intent.setAction(CloudBroadcastAction.API_ERROR_ACTION); intent.putExtra(CloudBroadcast.KEY_API_CODE, code); intent.putExtra(CloudBroadcast.KEY_API_MESSAGE, message); sendBroadcast(intent); } catch (Exception e) { e.printStackTrace(); } } buffer.clear(); } } } } } catch (Exception e) { Log.d("HDL===>", "disposeToken: 失败," + e); } return response; } /** * 根据code判断token是否失效 * * @param code 业务code * @return ture 失效 */ private boolean isTokenLoseByCode(int code) { return CloudCode.TOKEN_TIMEOUT == code || CloudCode.TOKEN_NOT_STANDARD == code || CloudCode.NO_TOKEN == code; } /** * 是否存在刷新头 */ private boolean isRefreshTokenHeader(Headers headers) { String signHeader = headers.get(SmartHeader.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", HDLCloudConfig.getInstance().getTokenHeaderPrefix() + token) .build(); } /** * 拦截器EncryptInterceptor会处理加密 * * @return token */ private String refreshToken() { final String cacheRefreshToken = SPUtils.getString(SPKey.REFRESH_TOKEN); if (TextUtils.isEmpty(cacheRefreshToken)) { return null; } 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(HDLCloudConfig.getInstance().getBaseUrl() + HdlCloudApi.LOGIN); builder.addHeader(SmartHeader.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()); JsonObject object = JsonParser.parseString(respString).getAsJsonObject(); JsonObject dataJson = object.get("data").getAsJsonObject(); String accessToken = dataJson.get("accessToken").getAsString(); String refreshToken = dataJson.get("refreshToken").getAsString(); if (!TextUtils.isEmpty(accessToken)) { HDLCloudConfig.getInstance().setToken(accessToken); } if (!TextUtils.isEmpty(refreshToken)) { HDLCloudConfig.getInstance().setRefreshToken(refreshToken); } return accessToken; } } else { Log.d("OKHTTP===>", "refreshToken: 失败了"); } } catch (Exception ignored) { Log.d("OKHTTP===>", "refreshToken: 失败,异常"); } return ""; } private void sendBroadcast(Intent intent) { HDLCloudConfig.getInstance().getContext().sendBroadcast(intent); } }