C#怎样通过url调用接口
在做一些项目过程中,我们常常总避免不了要调用接口,那么怎么通过url调用借口呢。我今天浅显的写一下。
首先要获取你访问链接的App Key 和 App Secret
那么什么是App Key 和 App Secret ,又有什么用呢?
App key简称API接口验证序号,是用于验证API接入合法性的。接入哪个网站的API接口,就需要这个网站允许才能够接入,如果简单比喻的话:可以理解成是登陆网站的用户名
App Secret简称API接口密钥,是跟App Key配套使用的,可以简单理解成是密码
App Key 和 App Secret 配合在一起,通过其他网站的协议要求,就可以接入API接口调用或使用API提供的各种功能和数据。
所以我们知道了App Key 和 App Secret ,我们还要获取一个令牌就是token.
(以下分割线之上都是引用于http://www.cnblogs.com/bukudekong/p/3829875.html)
Token,就是令牌,最大的特点就是随机性,不可预测。一般黑客或软件无法猜测出来。
那么,Token有什么作用?又是什么原理呢?
Token一般用在两个地方:
- 1)防止表单重复提交、
- 2)anti csrf攻击(跨站点请求伪造)。
两者在原理上都是通过session token来实现的。当客户端请求页面时,服务器会生成一个随机数Token,并且将Token放置到session当中,然后将Token发给客户端(一般通过构造hidden表单)。下次客户端提交请求时,Token会随着表单一起提交到服务器端。
然后,如果应用于“anti csrf攻击”,则服务器端会对Token值进行验证,判断是否和session中的Token值相等,若相等,则可以证明请求有效,不是伪造的。
不过,如果应用于“防止表单重复提交”,服务器端第一次验证相同过后,会将session中的Token值更新下,若用户重复提交,第二次的验证判断将失败,因为用户提交的表单中的Token没变,但服务器端session中Token已经改变了。
上面的session应用相对安全,但也叫繁琐,同时当多页面多请求时,必须采用多Token同时生成的方法,这样占用更多资源,执行效率会降低。因此,也可用cookie存储验证信息的方法来代替session Token。比如,应对“重复提交”时,当第一次提交后便把已经提交的信息写到cookie中,当第二次提交时,由于cookie已经有提交记录,因此第二次提交会失败。
不过,cookie存储有个致命弱点,如果cookie被劫持(xss攻击很容易得到用户cookie),那么又一次gameover。黑客将直接实现csrf攻击。
所以,安全和高效相对的。具体问题具体对待吧。
此外,要避免“加token但不进行校验”的情况,在session中增加了token,但服务端没有对token进行验证,根本起不到防范的作用。
还需注意的是,对数据库有改动的增删改操作,需要加token验证,对于查询操作,一定不要加token,防止攻击者通过查询操作获取token进行csrf攻击。但并不是这样攻击者就无法获得token,只是增大攻击成本而已。
-----------------------------------------------我是分割线------------------------------------------------------
知道了这些,我们就可以很轻松的调用接口了。下面是代码
using System.Net; using System.Security.Cryptography; using System.IO; using Newtonsoft.Json; namespace CRM.BLL.SalesClue { public class AddSalesClueLogic { public void PushSaleClueData(string companyUserName,string mobile,string email,string post,string saleClueSource,string companyType) { //AppSecret var AppSecret = "TUSDLFJSJ9877DLJFSLD9999SLDJFS"; var Appid = "51477108"; var access_token = ""; using (var wc = new WebClient()) { var result = wc.DownloadString(string.Format("http://www.xxxxx.com?appid={0}&secret={1}", Appid, AppSecret)); if (result.Contains("40001")) { return; } access_token = JsonConvert.DeserializeObject<Token>(result).access_token; } if (string.IsNullOrEmpty(access_token)) { return; } var Url = string.Format("http://www.xxxxx.com?access_token={0}", access_token); //模拟数据 var dict = new Dictionary<string, string>(); //这是一个实体对象,传入的参数 dict.Add("姓名", companyUserName); dict.Add("职务", post); dict.Add("手机", mobile); dict.Add("邮箱",email); dict.Add("公司", companyType); dict.Add("需求来源", saleClueSource); var data = JsonConvert.SerializeObject(dict); //数据签名 var sign = GetMd5(data + AppSecret).ToUpper(); try { var PostResutl = Post(Url, data, "application/json", 1000 * 3, Encoding.UTF8, "sign", sign); } catch (Exception ex) { } } public class Token { public string access_token { get; set; } public int expires_in { get; set; } } public static string GetMd5(string inputStr) { byte[] md5Bytes = Encoding.UTF8.GetBytes(inputStr); MD5 md5 = new MD5CryptoServiceProvider(); byte[] cryptString = md5.ComputeHash(md5Bytes); int len; StringBuilder sb = new StringBuilder(); len = cryptString.Length; for (int i = 0; i < len; i++) { sb.Append(cryptString[i].ToString("X2")); } return sb.ToString(); } public static string Post(string url, string data, string contentType, int timeoutMillis, Encoding encoding = null, string RequestKey = null, string RequestValue = null) { encoding = encoding ?? Encoding.UTF8; var request = WebRequest.Create(url); request.Method = "POST"; //request.Timeout = timeoutMillis; request.ContentType = contentType; if (!string.IsNullOrEmpty(RequestKey)) { request.Headers.Add(RequestKey, RequestValue); } using (var reqStream = request.GetRequestStream()) { using (var writer = new StreamWriter(reqStream, encoding)) { writer.Write(data); writer.Flush(); writer.Close(); } } using (var response = request.GetResponse()) { using (var stream = response.GetResponseStream()) { if (stream == null) { return string.Empty; } using (var reader = new StreamReader(stream, encoding)) { var s = reader.ReadToEnd(); return s; } } } } } }
接收接口的数据
public class HomeController : Controller { // GET: Home [HttpPost] public ActionResult Index() { //分配的AppSerect var AppSerect = "dafsdfaijlasjdfsajfd"; if (string.IsNullOrEmpty(Request.Headers["sign"])) { //不是推送的数据 return null; } var sign = Request.Headers["sign"]; System.IO.Stream s = Request.InputStream; var content = ""; using (var reader = new StreamReader(s, Encoding.UTF8)) { content = reader.ReadToEnd(); } var aydata = Newtonsoft.Json.JsonConvert.DeserializeObject<AYC>(content); if (GetMd5(content + AppSerect) == sign) { //推送的数据 } else { //不是推送的数据 } return Content(content); }