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);
|
}
|
}
|