/// <summary>
/// 获取token
/// </summary>
/// <param name="staffId"></param>
/// <returns></returns>
public JsonResult GetToken(string staffId)
{
ResultMsg resultMsg = null;
//判断参数是否合法
if (string.IsNullOrEmpty(staffId))
{
resultMsg = new ResultMsg();
resultMsg.StatusCode = (int)StatusCodeEnum.ParameterError;
resultMsg.Info = "staffId不合法";
resultMsg.Data = new Token();
return Json(resultMsg, JsonRequestBehavior.AllowGet);
}
//插入缓存
Token token = (Token)HttpRuntime.Cache.Get(staffId);
if (HttpRuntime.Cache.Get(staffId.ToString()) == null)
{
token = new Token();
token.StaffId = staffId;
token.SignToken = Guid.NewGuid();
token.ExpireTime = DateTime.Now.AddDays(1);
HttpRuntime.Cache.Insert(token.StaffId.ToString(), token, null, token.ExpireTime, TimeSpan.Zero);
}
//返回token信息
resultMsg = new ResultMsg();
resultMsg.StatusCode = (int)StatusCodeEnum.Success;
resultMsg.Info = "";
resultMsg.Data = token;
return Json(resultMsg, JsonRequestBehavior.AllowGet);
}
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Mvc;
using WebApplication_Token.Models;
namespace WebApplication_Token.Controllers
{
public class VerificationTokenController : Controller
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
ResultMsg resultMsg = null;
var request = Request;
var method = request.HttpMethod;
string staffid = string.Empty, timestamp = string.Empty, nonce = string.Empty, signature = string.Empty;
if (!string.IsNullOrEmpty(request.Headers["staffid"]))
{
staffid = HttpUtility.UrlDecode(request.Headers.GetValues("staffid").FirstOrDefault());
}
if (!string.IsNullOrEmpty(request.Headers["timestamp"]))
{
timestamp = HttpUtility.UrlDecode(request.Headers.GetValues("timestamp").FirstOrDefault());
}
if (!string.IsNullOrEmpty(request.Headers["nonce"]))
{
nonce = HttpUtility.UrlDecode(request.Headers.GetValues("nonce").FirstOrDefault());
}
if (!string.IsNullOrEmpty(request.Headers["signature"]))
{
signature = HttpUtility.UrlDecode(request.Headers.GetValues("signature").FirstOrDefault());
}
//GetToken方法不需要进行签名验证
if (filterContext.ActionDescriptor.ActionName == "GetToken")
{
base.OnActionExecuting(filterContext);
return;
}
//判断请求头是否包含以下参数
if (string.IsNullOrEmpty(staffid) || string.IsNullOrEmpty(timestamp) || string.IsNullOrEmpty(nonce) || string.IsNullOrEmpty(signature))
{
resultMsg = new ResultMsg();
resultMsg.StatusCode = (int)HttpStatusCode.PartialContent;
resultMsg.Info = "请求头缺少参数";
resultMsg.Data = new Token();
filterContext.Result = Json(resultMsg, JsonRequestBehavior.AllowGet);//返回json数据
base.OnActionExecuting(filterContext);
return;
}
//判断token是否有效
Token token = (Token)HttpRuntime.Cache.Get(staffid);
string signtoken = string.Empty;
if (token == null)
{
resultMsg = new ResultMsg();
resultMsg.StatusCode = (int)StatusCodeEnum.ParameterError;
resultMsg.Info = "token为null";
resultMsg.Data = new Token();
filterContext.Result = Json(resultMsg, JsonRequestBehavior.AllowGet);//返回json数据
base.OnActionExecuting(filterContext);
return;
}
else
{
signtoken = token.SignToken.ToString();
}
bool timespanvalidate = token.ExpireTime > Convert.ToDateTime(timestamp);
if (!timespanvalidate)
{
resultMsg = new ResultMsg();
resultMsg.StatusCode = (int)HttpStatusCode.PartialContent;
resultMsg.Info = "token已过期";
resultMsg.Data = new Token();
filterContext.Result = Json(resultMsg, JsonRequestBehavior.AllowGet);//返回json数据
base.OnActionExecuting(filterContext);
return;
}
//根据请求类型拼接参数
NameValueCollection coll = Request.Form;
string[] requestItem = coll.AllKeys;
Dictionary<string, string> sArray = new Dictionary<string, string>();
int j = 0;
for (j = 0; j < requestItem.Length; j++)
{
sArray.Add(requestItem[j], Request.Form[requestItem[j]]);
}
var queryStr = GetQueryString(sArray);
var _signature = GetSingnature(timestamp, queryStr.Item1, staffid, signtoken, queryStr.Item2);
if(signature!= _signature)
{
resultMsg = new ResultMsg();
resultMsg.StatusCode = (int)HttpStatusCode.PartialContent;
resultMsg.Info = "token不合法";
resultMsg.Data = new Token();
filterContext.Result = Json(resultMsg, JsonRequestBehavior.AllowGet);//返回json数据
base.OnActionExecuting(filterContext);
return;
}
}
/// <summary>
/// 获取签名字符串
/// </summary>
/// <param name="parames"></param>
/// <returns></returns>
public Tuple<string, string> GetQueryString(Dictionary<string, string> parames)
{
// 第一步:把字典按Key的字母顺序排序
IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parames);
IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator();
// 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder("");//签名字符串
StringBuilder queryStr = new StringBuilder("");//url参数
if (parames == null || parames.Count == 0)
{
return new Tuple<string, string>("", "");
}
while (dem.MoveNext())
{
string key = dem.Current.Key;
string value = dem.Current.Value;
if (!string.IsNullOrEmpty(key))
{
query.Append(key).Append(value);
queryStr.Append("&").Append(key).Append("=").Append(value);
}
}
return new Tuple<string, string>(query.ToString(), queryStr.ToString().Substring(1, queryStr.Length - 1));
}
/// <summary>
/// 根据参数计算签名
/// </summary>
/// <param name="timeStamp">发起请求时的时间戳(单位:毫秒)</param>
/// <param name="nonce">随机数</param>
/// <param name="staffId">当前请求用户StaffId</param>
/// <param name="signToken">signToken</param>
/// <param name="data">参数url</param>
/// <returns></returns>
public string GetSingnature(string timeStamp, string nonce, string staffId,string signToken, string data)
{
var hash = System.Security.Cryptography.MD5.Create();
//拼接签名
var signStr = timeStamp + nonce + staffId + signToken + data;
//将字符串中字符按升序排序
var sortStr = string.Concat(signStr.OrderBy(c => c));
var bytes = Encoding.UTF8.GetBytes(sortStr);
//使用MD5加密
var md5Val = hash.ComputeHash(bytes);
//把二进制转大写十六进制
StringBuilder result = new StringBuilder();
foreach (var c in md5Val)
{
result.Append(c.ToString("X2"));
}
return result.ToString().ToUpper();
}
}
}