本人在做速卖通自动抓取订单的需求时,由于查询订单时带入的access_token参数有时间限制,每隔10小时过期,需要重新刷新。
因此将个人的解决思路贴出来,已分享给大家。
ALi提供的授权规则如下:
于是我笨笨的直接拼接好URL:
https://gw.api.alibaba.com/openapi/param2/1/system.oauth2/getToken/YOUR_APPKEY?grant_type=refresh_token&client_id=YOUR_APPKEY&client_secret=YOUR_APPSECRET&refresh_token=REFRESH_TOKEN
将地址粘贴到浏览器,看是否能直接返回带令牌的Json给我,结果却不尽人意,返回的结果是:
{"error":"invalid_request","error_description":"Method not set to POST."}
既然是缺少POST提交,那我在提交改URL时,
WebRequest req = WebRequest.Create(urlPath);
req.Method = "POST";
将提交方式改为POST,这样应该就可以返回我所要的Json了吧,
结果还是不尽人意,程序会抛出异常,提示我未经授权。
看来有时候,直接拼接URL能返回想要的JSon,比如获取订单列表时,有的时候,这样拼接请求的URL,是不能得到返回值的。
所以在这种情况下,必须将那些参数通过请求的方式传递到Ali的服务端。


1 /// <summary> 2 /// 后台提交POST请求到指定的url,解析返回的Json数据 3 /// </summary> 4 /// <param name="RequestPara"></param> 5 /// <param name="Url"></param> 6 /// <returns></returns> 7 public string PostData(string RequestPara, string Url) 8 { 9 string result = ""; 10 WebRequest hr = HttpWebRequest.Create(Url); 11 12 byte[] buf = System.Text.Encoding.GetEncoding("utf-8").GetBytes(RequestPara); 13 hr.ContentType = "application/x-www-form-urlencoded"; 14 hr.ContentLength = buf.Length; 15 hr.Method = "POST"; 16 17 System.IO.Stream RequestStream = hr.GetRequestStream(); 18 RequestStream.Write(buf, 0, buf.Length); 19 RequestStream.Close(); 20 21 System.Net.WebResponse response = hr.GetResponse(); 22 Stream receiveStream = response.GetResponseStream(); 23 Encoding encode = Encoding.GetEncoding("utf-8"); 24 StreamReader sr = new StreamReader(receiveStream, encode); 25 char[] readbuffer = new char[2048]; 26 int n = sr.Read(readbuffer, 0, 2048); 27 while (n > 0) 28 { 29 string str = new string(readbuffer, 0, n); 30 result += str; 31 n = sr.Read(readbuffer, 0, 2048); 32 } 33 JavaScriptSerializer JSS = new JavaScriptSerializer(); 34 object obj = JSS.DeserializeObject(result); 35 Dictionary<string, object> datajson = (Dictionary<string, object>)obj; 36 37 //解析键值对数据 获取令牌 38 foreach (KeyValuePair<string, object> item in datajson) 39 { 40 if (item.Key == "access_token") 41 { 42 result = item.Value.ToString(); 43 return result; 44 } 45 } 46 47 return result; 48 } 49 50 /// <summary> 51 /// 获取accessToken令牌 52 /// </summary> 53 public string GetAccessToken() 54 { 55 //Dictionary<string, string> d = new Dictionary<string, string>(); 56 //d.Add("grant_type","refresh_token"); 57 //d.Add("client_id","2691656"); 58 //d.Add("client_secret","62rb1L2f77"); 59 //d.Add("refresh_token","d5b02bb0-4df4-4b04-8dc4-670e5829ea6a"); 60 //string ss = Sign("param2/1/system.oauth2/getToken/2691656",d); 61 62 //var aliExpressService = new AliExpressService(); 63 string access_token = ""; 64 //获取数据库中的账户信息 65 var account = new AliExpressService().GetAliExpressAcount(); 66 //检测说明access_token是否过期,如果过期则通过refresh_token重新获取,如果access_token没过期,直接使用,过期时长为10个小时 67 if (DateTime.Compare(account.LastUpdatedOn.Value, DateTime.Now.AddHours(-10)) > 0) 68 { 69 access_token = account.Access_token; 70 } 71 else 72 { 73 //获取令牌的URL 74 string url = ConfigurationManager.AppSettings["GetAccessTokenUrl"]; 75 //获取令牌所需的参数 76 string parm = "grant_type=refresh_token&client_id=" + account.AppKey + "&client_secret=" + account.AppSignatureKey + "&refresh_token=" + account.Refresh_token; 77 //获取令牌的方法 78 access_token = PostData(parm, url); 79 //修改数据库中的access_token 80 new AliExpressService().UpdateAccessToken(access_token, account.Account); 81 Logger.WriteLog("更新access_token成功,access_token的值为:" + access_token + ",更新时间为:" + DateTime.Now + "。"); 82 Console.WriteLine("更新access_token成功,access_token的值为:" + access_token + ",更新时间为:" + DateTime.Now + "。"); 83 } 84 85 return access_token; 86 }
获取到access_token后,后面的处理就十分简单了,判断下access_token是否过期,更新下数据库就可以了。