using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Net.Http.Headers; using System.Security.Cryptography; using System.Text; using Sog; using LitJson; using ProtoCSStruct; namespace HttpProxy { public class HeroAuth { // 测试地址 //private static readonly string _baseUrl = "http://180.76.56.137:30008"; // 正式地址 private static readonly string _baseUrl = "https://time.0sdk.com:35876"; private static string _getAccTokenUrl = "/user/getAccessToken"; private static string _getUserInfoUrl = "/v1/user/userInfo.lg"; private static string _postContentType = "multipart/form-data; boundary=-----------------"; // 游戏产品id private static string _productId; private static string _appKey; private static MD5 _md5; public static void Init(string productId, string appKey) { _productId = productId; _appKey = appKey; _md5 = MD5.Create(); _getAccTokenUrl = _baseUrl + _getAccTokenUrl; _getUserInfoUrl = _baseUrl + _getUserInfoUrl; _postContentType += DateTime.Now.Ticks.ToString("x"); } public static string CreateData(Dictionary keyVal) { JsonData data = new JsonData(); foreach (KeyValuePair pair in keyVal) { data[pair.Key] = new JsonData(pair.Value); } string jsonStr = data.ToJson(); string finalData = Convert.ToBase64String(Encoding.ASCII.GetBytes(jsonStr)); if (finalData.Length > 51) { char[] array = finalData.ToCharArray(); SwapChar(array, 1, 33); SwapChar(array, 10, 42); SwapChar(array, 18, 50); SwapChar(array, 19, 51); finalData = new string(array); } return finalData; } private static void SwapChar(char[] str, int idx1, int idx2) { if (idx1 >= 0 && idx2 >= 0 && str.Length > Math.Max(idx1, idx2)) { char tmp = str[idx1]; str[idx1] = str[idx2]; str[idx2] = tmp; } } private static string CreateParamsStr(Dictionary allParam) { // sign不参与签名 allParam.Remove("sign"); // market不参与签名, 虽然文档里没写, 但是对方给的示例代码里面排除了, 先排除, 有问题再回复 //allParam.Remove("market"); StringBuilder sb = new StringBuilder(); // 生成签名串, "k1=v1&k2=v2...&_appKey" var sortPairs = from pair in allParam orderby pair.Key select pair; foreach (KeyValuePair pair in sortPairs) { sb.Append(pair.Key).Append('=').Append(pair.Value).Append('&'); } sb.Append(_appKey); return sb.ToString(); } // 传入按字母排序后的请求参数, 不包含_appKey, 返回签名 private static string CalcSign(Dictionary allParam) { var str = CreateParamsStr(allParam); byte[] md5Hash = _md5.ComputeHash(Encoding.UTF8.GetBytes(str)); string md5Str = BitConverter.ToString(md5Hash).Replace("-", "").ToLower(); if (md5Str.Length > 23) { char[] array = md5Str.ToCharArray(); SwapChar(array, 1, 13); SwapChar(array, 5, 17); SwapChar(array, 7, 23); md5Str = new string(array); } return md5Str; } public static string GetAccessToken(string authCode) { var allParams = new Dictionary(); allParams["productId"] = _productId; allParams["code"] = authCode; allParams["timeStamp"] = HttpProxyServerUtils.GetTimeSecond().ToString(); // sign以外的字段全部添加到上面用于计算签名 allParams["sign"] = CalcSign(allParams); var content = new FormUrlEncodedContent(allParams); string ret = HttpUtils.HttpPost(_getAccTokenUrl, content, out bool exception); if (ret == null) { TraceLog.Error("HeroAuth.GetAccessToken HttpPost return null query failed"); return null; } TraceLog.Trace("HeroAuth.GetAccessToken ret {0}", ret); JsonData jsonData = JsonMapper.ToObject(ret); JsonData codeData = jsonData["code"]; int code = codeData != null ? (int)codeData : -1; if (code != 200) { TraceLog.Trace("HeroAuth.GetAccessToken res code {0} not 200 (succ)", code); return null; } return jsonData["data"].ToString(); } public static bool GetUserInfo(string accessToken, out string userId, out string userName) { userId = null; userName = null; var allParams = new Dictionary(); allParams["productId"] = _productId; allParams["accessToken"] = accessToken; allParams["timeStamp"] = HttpProxyServerUtils.GetTimeSecond().ToString(); // sign以外的字段全部添加到上面用于计算签名 allParams["sign"] = CalcSign(allParams); var content = new FormUrlEncodedContent(allParams); string ret = HttpUtils.HttpPost(_getUserInfoUrl, content, out bool exception); if (ret == null) { TraceLog.Error("HeroAuth.GetUserInfo HttpGet return null query failed"); return false; } TraceLog.Trace("HeroAuth.GetUserInfo ret {0}", ret); JsonData jsonData = JsonMapper.ToObject(ret); JsonData codeData = jsonData["code"]; int code = codeData != null ? (int)codeData : -1; if (code != 200) { TraceLog.Trace("HeroAuth.GetAccessToken res code {0} not 200 (succ)", code); return false; } JsonData data = jsonData["data"]; userId = data["userId"].ToString(); userName = data["userName"].ToString(); return true; } #if HERO_AUTH_POST_FORM_DATA public static string GetAccessToken(string authCode) { string timeSec = HttpProxyServerUtils.GetTimeSecond().ToString(); var allParams = new Dictionary(); allParams["productId"] = _productId; allParams["code"] = authCode; allParams["timeStamp"] = timeSec; MultipartFormDataContent content = new MultipartFormDataContent(); content.Headers.Add("ContentType", _postContentType); content.Add(new StringContent(_productId), "productId"); content.Add(new StringContent(authCode), "code"); content.Add(new StringContent(timeSec), "timeStamp"); content.Add(new StringContent(CalcSign(allParams)), "sign"); string ret = HttpUtils.HttpPost(_getAccTokenUrl, content, out bool exception); if (ret == null) { TraceLog.Error("HeroAuth.GetAccessToken HttpPost return null query failed"); return null; } TraceLog.Trace("HeroAuth.GetAccessToken ret {0}", ret); JsonData jsonData = JsonMapper.ToObject(ret); JsonData codeData = jsonData["code"]; int code = codeData != null ? (int)codeData : -1; if (code != 200) { TraceLog.Trace("HeroAuth.GetAccessToken res code {0} not 200 (succ)", code); return null; } return jsonData["data"].ToString(); } public static bool GetUserInfo(string accessToken, out string userId, out string userName) { userId = null; userName = null; string timeSec = HttpProxyServerUtils.GetTimeSecond().ToString(); var allParams = new Dictionary(); allParams["productId"] = _productId; allParams["accessToken"] = accessToken; allParams["timeStamp"] = timeSec; MultipartFormDataContent content = new MultipartFormDataContent(); content.Headers.Add("ContentType", _postContentType); content.Add(new StringContent(_productId), "productId"); content.Add(new StringContent(accessToken), "accessToken"); content.Add(new StringContent(timeSec), "timeStamp"); content.Add(new StringContent(CalcSign(allParams)), "sign"); string ret = HttpUtils.HttpPost(_getUserInfoUrl, content, out bool exception); if (ret == null) { TraceLog.Error("HeroAuth.GetUserInfo HttpGet return null query failed"); return false; } TraceLog.Trace("HeroAuth.GetUserInfo ret {0}", ret); JsonData jsonData = JsonMapper.ToObject(ret); JsonData codeData = jsonData["code"]; int code = codeData != null ? (int)codeData : -1; if (code != 200) { TraceLog.Trace("HeroAuth.GetAccessToken res code {0} not 200 (succ)", code); return false; } JsonData data = jsonData["data"]; userId = data["userId"].ToString(); userName = data["userName"].ToString(); return true; } #endif } }