搜索

查看: 3042|回复: 11

[ASP.NET] 通用 HTTP 签名组件的另类实现方式

[复制链接]
发表于 2023-5-4 11:31:16 | 显示全部楼层 |阅读模式
Editor 2023-5-4 11:31:16 3042 11 看全部
目录
  • 1、初衷
  • 2、思路
  • 3、直接看效果
  • 4、代码实现
  • HttpSignItem类
  • HttpSignSetting类
  • HttpSigner类
  • 5、附上仓库地址
    1、初衷
    开发中经常需要做一些接口的签名生成和校验工作,最开始的时候都是每个接口去按照约定单独实现,久而久之就变的非常难维护,因此就琢磨怎么能够写了一个比较通用的签名生成工具。

    2、思路
    采用链式调用的方式,使得签名的步骤可以动态拼凑组合。

    3、直接看效果
      //设置数据源
        var signSource = new Dictionary()
        {
            { "param1", "1" },
            { "param3", "3+" },
            { "param2", "2" }
        };
        var signer = new HttpSigner();
        signer.SetSignData(signSource);

        //设置数据源并配置规则
        signer.SetSignData(signSource, setting =>
        {
            //按参数名排序
            //result --> param1 param2 param3
            setting.IsOrderByWithKey = false;

            //是否对签名数据的参数值进行UrlEncode
            setting.IsDoUrlEncodeForSourceValue = false;

            //签名主体是否包含参数名
            setting.IsSignTextContainKey = true;
            //签名主体中参数和参数值的连接符(需要启用IsSignTextContainKey)
            setting.SignTextKeyValueSeparator = "=";
            //签名主体中不同参数项的连接符
            setting.SignTextItemSeparator = "&";
            //以上都开启后  --> param1=1&param2=2&param3=3

            //编码
            setting.DefaultEncoding = Encoding.UTF8;
        });

        //签名主体设置前缀
        signer.SetSignData(signSource).SetSignTextPrefix("TestPrefix");

        //签名主体设置后缀
        signer.SetSignData(signSource).SetSignTextSuffix("TestSuffix");

        //签名主体进行Base64
        signer.SetSignData(signSource).SetSignTextBase64();

        //签名主体进行MD5,(方法参数为签名结果是否转小写)
        signer.SetSignData(signSource).SetSignTextMD5(bool isToLower = true);

        //签名主体进行SHA1,(方法参数为签名结果是否转小写)
        signer.SetSignData(signSource).SetSignTextSHA1(bool isToLower = true);

        //获取签名结果
        string signString = signer.SetSignData(signSource).GetSignResult();

        //组合调用
        string signString = signer.SetSignData(signSource).SetSignTextBase64().SetSignTextMD5().SetSignTextSHA1();
    4、代码实现
    HttpSignItem类
    用于保存签名的参数集合。
    namespace JiuLing.CommonLibs.Security.HttpSign
    {
        internal class HttpSignItem
        {
            public string Key { get; set; }
            public string Value { get; set; }

            public HttpSignItem(string key, string value)
            {
                Key = key;
                Value = value;
            }
        }
    }
    HttpSignSetting类
    用于签名的基本配置。
    using System.Text;

    namespace JiuLing.CommonLibs.Security.HttpSign
    {
        ///
        /// 签名配置
        ///
        public class HttpSignSetting
        {
            ///
            /// 是否按参数名进行排序
            ///
            public bool IsOrderByWithKey { get; set; } = false;

            ///
            /// 是否对签名数据的参数值进行UrlEncode
            ///
            public bool IsDoUrlEncodeForSourceValue { get; set; } = false;

            ///
            /// 签名主体是否包含参数名
            ///
            public bool IsSignTextContainKey { get; set; } = true;

            ///
            /// 签名主体中参数和参数值的连接符(需要启用IsSignTextContainKey)
            ///
            public string SignTextKeyValueSeparator { get; set; } = "=";

            ///
            /// 签名主体中不同参数项的连接符
            ///
            public string SignTextItemSeparator { get; set; } = "&";

            ///
            /// 编码
            ///
            public Encoding DefaultEncoding { get; set; } = Encoding.UTF8;
        }
    }
    HttpSigner类
    签名组件的具体实现。
    using System;
    using System.Collections.Generic;
    using System.Linq;

    namespace JiuLing.CommonLibs.Security.HttpSign
    {
        ///
        /// 网络请求签名工具
        ///
        public class HttpSigner
        {
            ///
            /// 签名配置
            ///
            private readonly HttpSignSetting _setting = new HttpSignSetting();
            ///
            /// 最终的签名串
            ///
            private string _signString;

            ///
            /// 设置签名数据
            ///
            /// 待签名的键值对
            /// 配置签名规则
            ///
            ///
            public HttpSigner SetSignData(Dictionary signSource, Action setting = null)
            {
                setting?.Invoke(_setting);
                if (_setting == null)
                {
                    throw new ArgumentNullException("无效的签名配置", "setting");
                }

                if (signSource == null || signSource.Count == 0)
                {
                    throw new ArgumentException("待签名数据异常", nameof(signSource));
                }

                var signSourceList = new List(signSource.Count);
                foreach (var item in signSource)
                {
                    var itemValue = item.Value;
                    if (_setting.IsDoUrlEncodeForSourceValue)
                    {
                        itemValue = System.Web.HttpUtility.UrlEncode(itemValue, _setting.DefaultEncoding);
                    }
                    signSourceList.Add(new HttpSignItem(item.Key, itemValue));
                }

                if (_setting.IsOrderByWithKey)
                {
                    signSourceList = signSourceList.OrderBy(x => x.Key).ToList();
                }

                if (_setting.IsSignTextContainKey)
                {
                    _signString = string.Join(_setting.SignTextItemSeparator, signSourceList.Select(x => $"{x.Key}{_setting.SignTextKeyValueSeparator}{x.Value}"));
                }
                else
                {
                    _signString = string.Join(_setting.SignTextItemSeparator, signSourceList.Select(x => x.Value));
                }

                return this;
            }

            ///
            /// 签名主体设置前缀
            ///
            /// 前缀值
            ///
            public HttpSigner SetSignTextPrefix(string input)
            {
                _signString = $"{input}{_signString}";
                return this;
            }

            ///
            /// 签名主体设置后缀
            ///
            /// 后缀值
            ///
            public HttpSigner SetSignTextSuffix(string input)
            {
                _signString = $"{_signString}{input}";
                return this;
            }

            ///
            /// 签名主体设置后缀
            ///
            ///
            public HttpSigner SetUrlEncode()
            {
                _signString = System.Web.HttpUtility.UrlEncode(_signString, _setting.DefaultEncoding);
                return this;
            }

            ///
            /// 签名主体进行Base64
            ///
            ///
            public HttpSigner SetSignTextBase64()
            {
                _signString = Base64Utils.GetStringValue(_signString);
                return this;
            }

            ///
            /// 签名主体进行MD5
            ///
            /// 签名结果是否转小写
            ///
            public HttpSigner SetSignTextMD5(bool isToLower = true)
            {
                if (isToLower)
                {
                    _signString = MD5Utils.GetStringValueToLower(_signString);
                }
                else
                {
                    _signString = MD5Utils.GetStringValueToUpper(_signString);
                }
                return this;
            }

            ///
            /// 签名主体进行SHA1
            ///
            /// 签名结果是否转小写
            ///
            public HttpSigner SetSignTextSHA1(bool isToLower = true)
            {
                if (isToLower)
                {
                    _signString = SHA1Utils.GetStringValueToLower(_signString);
                }
                else
                {
                    _signString = SHA1Utils.GetStringValueToUpper(_signString);
                }
                return this;
            }

            ///
            /// 获取签名结果
            ///
            ///
            public string GetSignResult()
            {
                return _signString;
            }
        }
    }

    5、附上仓库地址
    以上代码包含在我的通用类库中,可以直接Nuget搜索JiuLing.CommonLibs安装。
    GitHub类库地址
    文章代码地址
    到此这篇关于通用 HTTP 签名组件的另类实现的文章就介绍到这了,更多相关HTTP 签名组件内容请搜索知鸟论坛以前的文章或继续浏览下面的相关文章希望大家以后多多支持知鸟论坛
  • 回复

    使用道具 举报

    发表于 2023-6-28 22:41:08 | 显示全部楼层
    伊索谗言 2023-6-28 22:41:08 看全部
    我看不错噢 谢谢楼主!知鸟论坛越来越好!
    回复

    使用道具 举报

    发表于 2023-6-29 14:20:12 | 显示全部楼层
    dxf17 2023-6-29 14:20:12 看全部
    感谢楼主的无私分享!要想知鸟论坛好 就靠你我他
    回复

    使用道具 举报

    发表于 2023-6-29 17:11:31 | 显示全部楼层
    Gordon520 2023-6-29 17:11:31 看全部
    论坛不能没有像楼主这样的人才啊!我会一直支持知鸟论坛
    回复

    使用道具 举报

    发表于 2023-6-29 17:24:56 | 显示全部楼层
    老橡树1 2023-6-29 17:24:56 看全部
    楼主,我太崇拜你了!我想我是一天也不能离开知鸟论坛
    回复

    使用道具 举报

    发表于 2023-6-29 17:27:26 | 显示全部楼层
    井底燕雀傥 2023-6-29 17:27:26 看全部
    我看不错噢 谢谢楼主!知鸟论坛越来越好!
    回复

    使用道具 举报

    发表于 2023-6-29 17:37:40 | 显示全部楼层
    计划你大爷计j 2023-6-29 17:37:40 看全部
    楼主,大恩不言谢了!知鸟论坛是最棒的!
    回复

    使用道具 举报

    发表于 2023-6-29 18:07:15 | 显示全部楼层
    普通人物怨 2023-6-29 18:07:15 看全部
    楼主太厉害了!楼主,I*老*虎*U!我觉得知鸟论坛真是个好地方!
    回复

    使用道具 举报

    发表于 2023-6-29 19:37:59 | 显示全部楼层
    风来时狂放 2023-6-29 19:37:59 看全部
    我看不错噢 谢谢楼主!知鸟论坛越来越好!
    回复

    使用道具 举报

    发表于 2023-6-30 09:47:14 | 显示全部楼层
    我的苦恼冉 2023-6-30 09:47:14 看全部
    既然你诚信诚意的推荐了,那我就勉为其难的看看吧!知鸟论坛不走平凡路。
    回复

    使用道具 举报

    • 您可能感兴趣
    点击右侧快捷回复 【请勿灌水】
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则 返回列表

    RSS订阅| SiteMap| 小黑屋| 知鸟论坛
    联系邮箱E-mail:zniao@foxmail.com
    快速回复 返回顶部 返回列表