仍是一如既往先上結構圖以下:html
上一講說明了redis,也謝謝心態的建議。這裏通過改進後的redis的地址ajax
固然這裏是加密了的,具體實現以下圖:redis
這裏提供的解密。算法
先把加密解密的幫助類放上來。json
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; namespace KuRuMi.Mio.DoMain.Infrastructure.Common { /// <summary> /// 對稱加密幫助類 /// </summary> public class CryptographyExtension { // 對稱加密算法提供器 private ICryptoTransform encryptor; // 加密器對象 private ICryptoTransform decryptor; // 解密器對象 private const int BufferSize = 1024; private static string dataKey = "XXXXXXXX"; public CryptographyExtension(string algorithmName, string key) { SymmetricAlgorithm provider = SymmetricAlgorithm.Create(algorithmName); provider.Key = Encoding.UTF8.GetBytes(key); provider.IV = new byte[] { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; encryptor = provider.CreateEncryptor(); decryptor = provider.CreateDecryptor(); } public CryptographyExtension(string key) : this("TripleDES", key) { } /// <summary> /// 加密算法 /// </summary> /// <param name="clearText"></param> /// <returns></returns> public string Encrypt(string clearText) { // 建立明文流 byte[] clearBuffer = Encoding.UTF8.GetBytes(clearText); MemoryStream clearStream = new MemoryStream(clearBuffer); // 建立空的密文流 MemoryStream encryptedStream = new MemoryStream(); CryptoStream cryptoStream = new CryptoStream(encryptedStream, encryptor, CryptoStreamMode.Write); // 將明文流寫入到buffer中 // 將buffer中的數據寫入到cryptoStream中 int bytesRead = 0; byte[] buffer = new byte[BufferSize]; do { bytesRead = clearStream.Read(buffer, 0, BufferSize); cryptoStream.Write(buffer, 0, bytesRead); } while (bytesRead > 0); cryptoStream.FlushFinalBlock(); // 獲取加密後的文本 buffer = encryptedStream.ToArray(); string encryptedText = Convert.ToBase64String(buffer); return encryptedText; } /// <summary> /// 解密算法 /// </summary> /// <param name="encryptedText"></param> /// <returns></returns> public string Decrypt(string encryptedText) { byte[] encryptedBuffer = Convert.FromBase64String(encryptedText); Stream encryptedStream = new MemoryStream(encryptedBuffer); MemoryStream clearStream = new MemoryStream(); CryptoStream cryptoStream = new CryptoStream(encryptedStream, decryptor, CryptoStreamMode.Read); int bytesRead = 0; byte[] buffer = new byte[BufferSize]; do { bytesRead = cryptoStream.Read(buffer, 0, BufferSize); clearStream.Write(buffer, 0, bytesRead); } while (bytesRead > 0); buffer = clearStream.GetBuffer(); string clearText = Encoding.UTF8.GetString(buffer, 0, (int)clearStream.Length); return clearText; } /// <summary> /// 加密 /// </summary> /// <param name="clearText"></param> /// <param name="key"></param> /// <returns></returns> public static string Encrypts(string clearText) { CryptographyExtension helper = new CryptographyExtension(dataKey); return helper.Encrypt(clearText); } /// <summary> /// 解密 /// </summary> /// <param name="encryptedText"></param> /// <param name="key"></param> /// <returns></returns> public static string Decrypts(string encryptedText) { CryptographyExtension helper = new CryptographyExtension(dataKey); return helper.Decrypt(encryptedText); } } }
完成這一些後,下面來看看簽名驗證。原本是寫好了token+簽名的驗證,由於token目前還有些問題後來刪掉了,改用簽名驗證。服務器
這個方法是放在client端返回加密後的key。由於博主的項目全是post請求,這裏就沒有補充get請求。app
public static T Post<T>(string url, string data, string appid) { byte[] bytes = Encoding.UTF8.GetBytes(data); HttpWebRequest request = WebRequest.CreateHttp(url) as HttpWebRequest; //加入到頭信息中 request.Headers.Add("appid", appid);//當前的用戶的請求id request.Headers.Add("sign", GetSignature());//簽名驗證 //寫數據 request.Method = "POST"; request.ContentLength = bytes.Length; request.ContentType = "application/json"; Stream reqstream = request.GetRequestStream(); reqstream.Write(bytes, 0, bytes.Length); //讀數據 request.Timeout = 30000; request.Headers.Set("Pragma", "no-cache"); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); Stream streamReceive = response.GetResponseStream(); StreamReader streamReader = new StreamReader(streamReceive, Encoding.UTF8); string strResult = streamReader.ReadToEnd(); //關閉流 reqstream.Close(); streamReader.Close(); streamReceive.Close(); request.Abort(); response.Close(); return JsonConvert.DeserializeObject<T>(strResult); }
而後是調用:ide
頁面上的寫法就是在ajax裏面加入請求頭post
$(function () { $("#regist").click(function () { var data = { userName: $("#text_r").val(), email: $("#email_r").val(), passWord: $("#password_r").val() }; debugger; $.ajax({ //"Content-Type":"application/ json" //這裏若是將此放入到headers裏面會出現傳入DTO參數的時候爲空 headers: { appid: "2xl7w0Doqog=", sign: "MwOMp5bATVf1N2qNmAxW1GL1mduieOjsLHe45frBuISIpRE9OWncZ569sZraRQnwmWuQHNmJZJjCT/FaWsSiZw=="}, type: 'post', datatype: 'json', data: data, url: 'http://localhost:13292/Api/App/DataForAjax', success: function (data) { $('small').html(data); $('small').delay(3000).hide(0); } }); });
//"Content-Type":"application/ json" //這裏若是將此放入到headers裏面會出現傳入DTO參數的時候爲空
![](http://static.javashuo.com/static/loading.gif)
這裏就是加上了
Content-Type":"application/ json形成的
去掉了以後
下面是filter代碼ui
using KuRuMi.Mio.AppService.Common; using KuRuMi.Mio.AppService.Models; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Web; using System.Web.Http.Controllers; using System.Web.Http.Filters; namespace KuRuMi.Mio.AppService.Filter { public class SignSecretFilter : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { ResultMsg resultMsg = null; string appId = string.Empty; string sign = string.Empty; if (actionContext.Request.Headers.Contains("appid")) { appId = HttpUtility.UrlDecode(actionContext.Request.Headers.GetValues("appid").FirstOrDefault()); } if (actionContext.Request.Headers.Contains("sign")) { sign = HttpUtility.UrlDecode(actionContext.Request.Headers.GetValues("sign").FirstOrDefault()); } //判斷請求頭是否包含如下參數 if (string.IsNullOrEmpty(appId) || string.IsNullOrEmpty(sign)) { resultMsg = new ResultMsg(); resultMsg.StatusCode = (int)StatusCodeEnum.ParameterError; resultMsg.Info = StatusCodeEnum.ParameterError.GetEnumText(); resultMsg.Data = ""; actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(resultMsg)); base.OnActionExecuting(actionContext); return; } //驗證簽名算法 bool result = SignExtension.Validate(appId, sign); if (!result) { resultMsg = new ResultMsg(); resultMsg.StatusCode = (int)StatusCodeEnum.HttpRequestError; resultMsg.Info = StatusCodeEnum.HttpRequestError.GetEnumText(); resultMsg.Data = ""; actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(resultMsg)); base.OnActionExecuting(actionContext); return; } } } }
服務器端驗證簽名的方法:
using KuRuMi.Mio.DoMain.Infrastructure.Common; using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Web; namespace KuRuMi.Mio.AppService.Common { /// <summary> /// 判斷簽名算法 /// </summary> public class SignExtension { private static readonly string keys = "Kurumi"; /// <summary> /// 判斷簽名算法 /// </summary> /// <param name="appId"></param> /// <param name="url"></param> /// <param name="sign">簽名</param> /// <returns></returns> public static bool Validate(string appId, string sign) { byte[] bytes = Encoding.UTF8.GetBytes(ConfigManagerExtension.SecretKey); string signs = string.Empty; if (appId != "1000") signs = CryptographyExtension.Decrypts(appId) + keys; else signs = appId + keys; byte[] val = Encoding.UTF8.GetBytes(string.Concat(signs.OrderBy(c => c)));//排序 string key = null; using (HMACSHA512 SecretKey = new HMACSHA512(bytes)) { var SecretKeyBytes = SecretKey.ComputeHash(val); key = Convert.ToBase64String(SecretKeyBytes); } return (sign.Equals(key, StringComparison.Ordinal)); } } }