给接口添加签名验证

例如一个URL如下http://xx.xx?key=value&key=value 现在要加上签名验证
建议加上时间戳参数防止一个接口在短时间内被多次请求
然后URL就变成了了http://xx.xx?key=value&key=value&timestamp=时间戳
sign我这里用MD5加密
前端获取sign方法
将要提交的参数提取出来将&符号去掉然后把参数排序,将排序后的参数拼接成一个字符串并且加上后端给的秘钥,然后在使用MD5加密就生成了sign
然后URL就变成了了http://xx.xx?key=value&key=value&timestamp=时间戳&sign=签名
现在就可以提交了。
我们后端接请求后将所有参数放入一个字典,记得将sign参数移除,也可以在存放字典的时候就排除掉sign参数。
然后将字典的key排序,然后遍历字典将参数拼接成一个字符串并在末尾加上秘钥。
例如key1=value+key2=value+秘钥 这里的时间戳也算key,value。
具体代码如下
        /// <summary>
        /// 获取签名
        /// </summary>
        /// <param name="keyValues">URL参数</param>
        /// <param name="secret">秘钥</param>
        /// <returns></returns>
        public static string GetSign(Dictionary<string, string> keyValues, string secret)
        {
            keyValues.Remove("sign");
            var orderkeyValues = keyValues.Keys.OrderBy(x => x);
            StringBuilder builder = new StringBuilder();
            foreach (var item in keyValues)
            {
                builder.Append($"{item.Key}={item.Value}");
            }
            builder.Append(secret);
            var md5 = MD5.Create();
            var bytes = Encoding.Default.GetBytes(builder.ToString());
            var md5bytes = md5.ComputeHash(bytes);
            return BitConverter.ToString(md5bytes).Replace("-","");           
        }

        public static (bool,string) verifySign(Dictionary<string, string> keyValues)
        {     
            var pasttime = System.Configuration.ConfigurationManager.AppSettings["pastdate"];
            var secret = System.Configuration.ConfigurationManager.AppSettings["secret"];
            var timestamp = keyValues["timestamp"];
            var sign = keyValues["sign"];
            if (timestamp != ""&& timestamp != null)
            {
                DateTime? date = webservice.timestamp.StampToDateTime(timestamp);
                if (date is null)  //时间转换失败
                {
                    return (false, "时间戳转换失败");
                }
                else
                {
                    DateTime time = DateTime.Now;
                    var pastdatetime = date?.AddMinutes(double.Parse(pasttime));
                    if (pastdatetime > time)
                    {
                        string gensign = GetSign(keyValues, secret);
                        if (gensign == sign)
                        {
                            return (true, "");
                        }
                        else
                        {
                            return (false, "签名验证失败");
                        }
                    }
                    else
                    {   //签名过期

                        return (false, "签名过期");
                    }

                }
            }
            return (false, "签名验证失败");
        }
posted @ 2021-09-18 17:49  猿外  阅读(646)  评论(0编辑  收藏  举报