zoukankan      html  css  js  c++  java
  • MVC 统一验证Token demo

    /// <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();
    
            }
        }
    }
  • 相关阅读:
    Apache Shiro 使用手册(二)Shiro 认证
    jdk 环境变量
    IDEA 相关整理
    mysql 相关命令
    hbase 迁库移库步骤
    Linux 常用指令整理
    springboot aop + logback + 统一异常处理 打印日志
    查看jar包的jdk版本
    maven 将jar包推送到自己本机的maven库
    jar包内的文件导出的注意点
  • 原文地址:https://www.cnblogs.com/Mzg121584668/p/11275183.html
Copyright © 2011-2022 走看看