using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Security.Cryptography; using System.Text; using RestSharp; namespace SiriIntents.Server { public class HttpUtil { #region **********全局常量********** /// /// 固定域名,正式环境 /// 公共域名就近解析 /// public const string GlobalRequestHttpsHost = "https://nearest.hdlcontrol.com"; //public const string GlobalRequestHttpsHost = "http://59.41.255.150:7777"; //public const string GlobalRequestHttpsHost = "https://test-gz.hdlcontrol.com";//mmmm /// /// RegionMark /// public const string RegionMark = "HDL"; /// /// 请求超时时间 /// public const int TIME_OUT = 15; /// /// 特殊接口请求超时时间 /// public const int TIME_OUT_LONG = 20; /// /// Bearer 暂时设为空,从登陆成功的返回的headerPrefix参数动态获取 /// //public const string TOKEN_BEARER = "Bearer "; #endregion #region **********网络请求封装********** /// /// POST请求方法 body参数 /// 针对住宅相关接口封装 /// 调用住宅当前所在区域域名 /// 如果是分享住宅,使用主人的token进行相关操作 /// /// /// /// /// public static ResponsePackNew RequestHttpsPostFroHome(string apiPath, string bodyParameterJson, int mTimeout = TIME_OUT) { string urlHead = HttpServerRequest.Ins.DataManager.RegionUrl; //var replaceToken = ""; //if (DB_ResidenceData.residenceData.residecenInfo.IsOthreShare) //{ // replaceToken = DB_ResidenceData.residenceData.MasterToken; //} return RequestHttps(Method.POST, apiPath, bodyParameterJson, null, null, urlHead, "", mTimeout); } /// /// POST请求方法 body参数 /// /// /// /// /// /// /// /// public static ResponsePackNew RequestHttpsPost(string apiPath, string bodyParameterJson, string urlHead = "", string replaceToken = "", int mTimeout = TIME_OUT) { return RequestHttps(Method.POST, apiPath, bodyParameterJson, null, null, urlHead, replaceToken, mTimeout); } /// /// POST请求方法 queryDictionary /// /// /// /// /// /// /// /// public static ResponsePackNew RequestHttpsPost(string apiPath, Dictionary queryDictionary, string urlHead = "", string replaceToken = "", int mTimeout = TIME_OUT) { return RequestHttps(Method.POST, apiPath, null, queryDictionary, null, urlHead, replaceToken, mTimeout); } /// /// 通用 请求服务器方法 /// /// /// /// /// /// /// /// /// /// static ResponsePackNew RequestHttpsBase(Method method, string apiPath, string bodyParameterJson = null, Dictionary queryDictionary = null, Dictionary urlSegmentDictionary = null, string urlHead = "", string replaceToken = "", int mTimeout = TIME_OUT) { //Dome模式登录 #region HttpWebRequest try { string requestFullUrl = urlHead + apiPath; RestClient client = new RestClient(requestFullUrl); RestRequest request = new RestRequest(method); request.Timeout = mTimeout * 1000; request.AddHeader("content-type", "application/json"); request.AddHeader("Authorization", HttpServerRequest.Ins.DataManager.AccessToken); if (bodyParameterJson != null) { request.AddParameter("application/json", bodyParameterJson, ParameterType.RequestBody); } if (queryDictionary != null) { foreach (var data in queryDictionary) { request.AddQueryParameter(data.Key, data.Value.ToString()); } } if (urlSegmentDictionary != null) { foreach (var data in urlSegmentDictionary) { request.AddUrlSegment(data.Key, data.Value.ToString()); } } IRestResponse response = client.Execute(request); if (response.StatusCode == HttpStatusCode.OK) { try { ResponsePackNew revertObj = new ResponsePackNew() { }; revertObj = Newtonsoft.Json.JsonConvert.DeserializeObject(response.Content); //*****一些判空处理***************** if (revertObj.Code == null) { revertObj.Code = StateCode.DATA_EXCEPTION; } if (revertObj.Data == null) { revertObj.Data = ""; } //*****一些判空处理***************** return revertObj; } catch (Exception ex) { return new ResponsePackNew() { Code = StateCode.DATA_EXCEPTION }; } } else { return new ResponsePackNew() { Code = StateCode.NETWORK_ERROR }; } } catch (Exception ex) { return new ResponsePackNew() { Code = StateCode.NETWORK_ERROR }; } #endregion } /// /// 通用 请求服务器方法 /// 增加token过期处理 /// /// /// /// /// /// /// /// /// /// public static ResponsePackNew RequestHttps(Method method, string apiPath, string bodyParameterJson = null, Dictionary queryDictionary = null, Dictionary urlSegmentDictionary = null, string urlHead = "", string replaceToken = "", int mTimeout = TIME_OUT) { var responsePackNew = RequestHttpsBase(method, apiPath, bodyParameterJson, queryDictionary, urlSegmentDictionary, urlHead, replaceToken, mTimeout); //*****************Token过期处理***************** if (responsePackNew.Code == StateCode.TOKEN_EXPIRED) { //刷新Token if (RefreshToken()) { return RequestHttpsBase(method, apiPath, bodyParameterJson, queryDictionary, urlSegmentDictionary, urlHead, replaceToken, mTimeout); } else { return responsePackNew; } } //*****************Token过期处理***************** return responsePackNew; } /// /// 刷新 Token /// /// static bool RefreshToken() { try { var requestJson = GetSignRequestJson(new RefreshTokenObj() { refreshToken = HttpServerRequest.Ins.DataManager.RefreshToken, }); var revertObj = RequestHttpsBase(Method.POST, NewAPI.API_POST_Login, requestJson); if (revertObj.Code == StateCode.SUCCESS) { var revertData = Newtonsoft.Json.JsonConvert.DeserializeObject(revertObj.Data.ToString()); HttpServerRequest.Ins.DataManager.AccessToken = revertData.headerPrefix + revertData.accessToken; HttpServerRequest.Ins.DataManager.RefreshToken = revertData.refreshToken; return true; } return false; } catch { return false; } } #endregion #region **********签名校验********** /// /// /// const string APP_KEY = "QWERREWQ";//"COSDFPIN"; /// /// /// const string SECRET_KEY = "CPBUCTRLCPBUABCD";//"COSDFPJDCOSDFPJT"; /// /// 获取当前时间戳值 /// /// static string GetTimestamp() { System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 当地时区 return ((long)(DateTime.Now - startTime).TotalMilliseconds).ToString(); // 相差秒数 //return ((long)(DateTime.Now - startTime).TotalSeconds).ToString(); // 相差秒数 } /// /// /// /// /// static string SignMD5Encrypt(string s) { byte[] sign = MD5.Create().ComputeHash(UTF8Encoding.UTF8.GetBytes(s)); string signstr = string.Empty; foreach (byte item in sign) { signstr += item.ToString("X2"); } return signstr.ToLower(); } /// /// 判断当前值是否需要参与签名,保持跟云端一致 /// 空字符串不参与 /// 数组,集合,对象不参与 /// /// /// static bool IfValueNeedSign(string valueStr) { if (string.IsNullOrEmpty(valueStr) || valueStr.StartsWith("{") || valueStr.StartsWith("[")) { return false; } return true; } /// /// 2020-11-02 /// 基础服务的接口都要校验sign /// 计算sign签名 /// /// public static string GetSignRequestJson(object requestObj,Dictionary paramDictionary = null) { try { //1. 将model实体转为Dictionary if (paramDictionary == null) { paramDictionary = Newtonsoft.Json.JsonConvert.DeserializeObject>(Newtonsoft.Json.JsonConvert.SerializeObject(requestObj)); } //2. 计算sign if (paramDictionary != null) { paramDictionary.Add("appKey", APP_KEY); paramDictionary.Add("timestamp", GetTimestamp()); //2.1 字典升序 paramDictionary = paramDictionary.OrderBy(o => o.Key).ToDictionary(o => o.Key, p => p.Value); //2.2 拼接按URL键值对 string str = string.Empty; foreach (KeyValuePair item in paramDictionary) { //Value为null不参加校验 if (item.Value != null) { //Value.ToString()为null或者""也不参加校验 //if (!string.IsNullOrEmpty(item.Value.ToString()) && (item.Value is string || item.Value.GetType().IsValueType)) //{ //检测当前参数是否需要参与校验 if (IfValueNeedSign(item.Value.ToString())) { //如果是bool类型,要转小写 if (item.Value is bool) { str += item.Key + "=" + item.Value.ToString().ToLower() + "&"; } else { str += item.Key + "=" + item.Value.ToString() + "&"; } } } } //2.3 拼接SECRET_KEY str = str.Substring(0, str.Length - 1) + SECRET_KEY; //2.4 MD5转换+转小写 var signstr = SignMD5Encrypt(str); paramDictionary.Add("sign", signstr); var signResult = Newtonsoft.Json.JsonConvert.SerializeObject(paramDictionary); return signResult; } else { return ""; } } catch { return ""; } } #endregion } /// /// 响应参数 /// [Serializable] public class ResponsePackNew { /// /// 响应状态码 /// public string Code; /// /// 响应内容 /// public object Data; /// /// 响应错误信息 /// public string message = ""; /// /// 这个是请求错误时的扩展数据,以后所有的附带扩展数据都会放在这里面动态维护 /// public object extra; ///// ///// isSuccess ///// //public bool isSuccess; ///// ///// timestamp ///// //public string timestamp; } }