package com.hdl.linkpm.sdk.core.interceptor;
|
|
import android.net.Uri;
|
import android.text.TextUtils;
|
|
import androidx.annotation.NonNull;
|
|
import com.google.gson.JsonElement;
|
import com.google.gson.JsonObject;
|
import com.google.gson.JsonParser;
|
import com.google.gson.reflect.TypeToken;
|
import com.hdl.hdlhttp.utils.GsonConvert;
|
import com.hdl.linkpm.sdk.HDLLinkPMSdk;
|
import com.hdl.linkpm.sdk.core.interceptor.HDLSmartHeader;
|
import com.hdl.linkpm.sdk.utils.HDLMD5Utils;
|
import com.hdl.linkpm.sdk.utils.HDLSDKLog;
|
|
import java.io.IOException;
|
import java.io.UnsupportedEncodingException;
|
import java.net.URLDecoder;
|
import java.nio.charset.Charset;
|
import java.util.ArrayList;
|
import java.util.Collections;
|
import java.util.List;
|
import java.util.Map;
|
|
import okhttp3.FormBody;
|
import okhttp3.Headers;
|
import okhttp3.Interceptor;
|
import okhttp3.MediaType;
|
import okhttp3.Request;
|
import okhttp3.RequestBody;
|
import okhttp3.Response;
|
import okio.Buffer;
|
|
/**
|
* Created by Tong on 2021/11/4.
|
* 加密并自动补充参数,appKey、timestamp
|
* 只支持表单、json
|
* 最终json方式提交
|
*/
|
public class HDLEncryptInterceptor implements Interceptor {
|
|
|
@NonNull
|
@Override
|
public Response intercept(@NonNull Chain chain) throws IOException {
|
Request request = chain.request();
|
Headers headers = request.headers();
|
if (!isIgnoreSignHeader(headers)) {
|
return chain.proceed(encrypt(request));
|
}
|
|
return chain.proceed(request);
|
}
|
|
|
/**
|
* 添加sign字段
|
*/
|
private Request encrypt(Request request) {
|
final String timestamp = String.valueOf(System.currentTimeMillis());
|
final String appKey = HDLLinkPMSdk.getAppKey();
|
final String appSecret = HDLLinkPMSdk.getAppSecret();
|
final JsonObject json = getBodyJson(request);
|
if (json != null) {
|
json.addProperty("appKey", appKey);
|
json.addProperty("timestamp", timestamp);
|
json.addProperty("sign", getSign(json, appSecret));
|
final RequestBody requestBody = RequestBody.create(json.toString(), MediaType.parse("application/json;charset=UTF-8"));
|
return request.newBuilder().post(requestBody)
|
.build();
|
}
|
return request;
|
}
|
|
|
/**
|
* 是否忽略自定义的加密头
|
*/
|
private boolean isIgnoreSignHeader(Headers headers) {
|
String signHeader = headers.get(HDLSmartHeader.IGNORE_SIGN_HEADER);
|
|
return !TextUtils.isEmpty(signHeader);
|
}
|
|
private JsonObject getBodyJson(Request request) {
|
|
RequestBody body = request.body();
|
if (body instanceof FormBody) {
|
JsonObject object = new JsonObject();
|
FormBody formBody = (FormBody) body;
|
for (int i = 0; i < formBody.size(); i++) {
|
object.addProperty(formBody.encodedName(i), formBody.value(i));
|
}
|
return object;
|
} else {
|
//json格式
|
try {
|
String bodyString = getBodyString(request);
|
if (!TextUtils.isEmpty(bodyString)) {
|
final JsonElement parseString = JsonParser.parseString(bodyString);
|
return parseString.getAsJsonObject();
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
|
}
|
return null;
|
}
|
|
private String getBodyString(Request request) {
|
try {
|
RequestBody body = request.body();
|
if (body != null) {
|
Buffer buffer = new Buffer();
|
body.writeTo(buffer);
|
Charset charset = Charset.forName("UTF-8");
|
MediaType contentType = body.contentType();
|
charset = contentType.charset(charset);
|
return buffer.readString(charset);
|
}
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
return "";
|
}
|
|
|
/**
|
* 需要按字母排序
|
*
|
* @param json 所有字段使用urlParameter拼接,除了appSecret
|
*/
|
private String getSign(JsonObject json, String appSecret) {
|
String builder = jsonToUrlParameter(json) +
|
appSecret;
|
return HDLMD5Utils.encodeMD5(builder);
|
}
|
|
|
private String jsonToUrlParameter(JsonObject object) {
|
final Map<String, String> map = GsonConvert.getGson().fromJson(object, new TypeToken<Map<String, String>>() {
|
}.getType());
|
final Uri.Builder builder = new Uri.Builder();
|
List<String> list = new ArrayList<>(map.keySet());
|
Collections.sort(list);
|
for (String key : list) {
|
//判断当前值是否需要参与签名,保持跟云端一致
|
if (IfValueNeedSign(map.get(key))) {
|
builder.appendQueryParameter(key, map.get(key));
|
// HDLSDKLog.e("要签名:" + key + " :" + map.get(key));
|
} else {
|
// HDLSDKLog.e("不需要签名:" + key + " :" + map.get(key));
|
}
|
}
|
return builder.build().getQuery();
|
}
|
|
/**
|
* 判断当前值是否需要参与签名,保持跟云端一致
|
* 空字符串不参与
|
* 数组,集合,对象不参与
|
*
|
* @param valueStr
|
* @return
|
*/
|
private static boolean IfValueNeedSign(String valueStr) {
|
if (TextUtils.isEmpty(valueStr))
|
return false;
|
final char[] strChar = valueStr.substring(0, 1).toCharArray();
|
final char firstChar = strChar[0];
|
//System.out.println("getJSONType firstChar = "+firstChar);
|
if (firstChar != '{' && firstChar != '[')
|
return true;
|
|
return false;
|
}
|
// /**
|
// * 判断当前值是否需要参与签名,保持跟云端一致
|
// * 空字符串不参与
|
// * 数组,集合,对象不参与
|
// *
|
// * @param inputValueStr
|
// * @return
|
// */
|
// private static boolean IfValueNeedSign(String inputValueStr) {
|
// if (TextUtils.isEmpty(inputValueStr))
|
// return false;
|
// try {
|
// //先解码
|
// String valueStr = URLDecoder.decode(inputValueStr, "utf-8");
|
// final char[] strChar = valueStr.substring(0, 1).toCharArray();
|
// final char firstChar = strChar[0];
|
// //System.out.println("getJSONType firstChar = "+firstChar);
|
// if (firstChar != '{' && firstChar != '[') {
|
// return true;
|
// }
|
// return false;
|
// } catch (UnsupportedEncodingException e) {
|
// e.printStackTrace();
|
// return false;
|
// }
|
//
|
// }
|
|
}
|