ToB企服应用市场:ToB评测及商务社交产业平台

标题: 通用 HTTP 签名组件的另类实现 [打印本页]

作者: 怀念夏天    时间: 2022-9-26 23:12
标题: 通用 HTTP 签名组件的另类实现
1、初衷

开发中经常需要做一些接口的签名生成和校验工作,最开始的时候都是每个接口去按照约定单独实现,久而久之就变的非常难维护,因此就琢磨怎么能够写了一个比较通用的签名生成工具。
2、思路

采用链式调用的方式,使得签名的步骤可以动态拼凑组合。
3、直接看效果
  1.     //设置数据源
  2.     var signSource = new Dictionary<string, string>()
  3.     {
  4.         { "param1", "1" },
  5.         { "param3", "3+" },
  6.         { "param2", "2" }
  7.     };
  8.     var signer = new HttpSigner();
  9.     signer.SetSignData(signSource);
  10.     //设置数据源并配置规则
  11.     signer.SetSignData(signSource, setting =>
  12.     {
  13.         //按参数名排序
  14.         //result --> param1 param2 param3
  15.         setting.IsOrderByWithKey = false;
  16.         //是否对签名数据的参数值进行UrlEncode
  17.         setting.IsDoUrlEncodeForSourceValue = false;
  18.         //签名主体是否包含参数名
  19.         setting.IsSignTextContainKey = true;
  20.         //签名主体中参数和参数值的连接符(需要启用IsSignTextContainKey)
  21.         setting.SignTextKeyValueSeparator = "=";
  22.         //签名主体中不同参数项的连接符
  23.         setting.SignTextItemSeparator = "&";
  24.         //以上都开启后  --> param1=1&param2=2&param3=3
  25.         //编码
  26.         setting.DefaultEncoding = Encoding.UTF8;
  27.     });
  28.     //签名主体设置前缀
  29.     signer.SetSignData(signSource).SetSignTextPrefix("TestPrefix");
  30.     //签名主体设置后缀
  31.     signer.SetSignData(signSource).SetSignTextSuffix("TestSuffix");
  32.     //签名主体进行Base64
  33.     signer.SetSignData(signSource).SetSignTextBase64();
  34.     //签名主体进行MD5,(方法参数为签名结果是否转小写)
  35.     signer.SetSignData(signSource).SetSignTextMD5(bool isToLower = true);
  36.     //签名主体进行SHA1,(方法参数为签名结果是否转小写)
  37.     signer.SetSignData(signSource).SetSignTextSHA1(bool isToLower = true);
  38.     //获取签名结果
  39.     string signString = signer.SetSignData(signSource).GetSignResult();
  40.     //组合调用
  41.     string signString = signer.SetSignData(signSource).SetSignTextBase64().SetSignTextMD5().SetSignTextSHA1();
复制代码
4、代码实现

HttpSignItem类

用于保存签名的参数集合。
  1. namespace JiuLing.CommonLibs.Security.HttpSign
  2. {
  3.     internal class HttpSignItem
  4.     {
  5.         public string Key { get; set; }
  6.         public string Value { get; set; }
  7.         public HttpSignItem(string key, string value)
  8.         {
  9.             Key = key;
  10.             Value = value;
  11.         }
  12.     }
  13. }
复制代码
HttpSignSetting类

用于签名的基本配置。
  1. using System.Text;
  2. namespace JiuLing.CommonLibs.Security.HttpSign
  3. {
  4.     /// <summary>
  5.     /// 签名配置
  6.     /// </summary>
  7.     public class HttpSignSetting
  8.     {
  9.         /// <summary>
  10.         /// 是否按参数名进行排序
  11.         /// </summary>
  12.         public bool IsOrderByWithKey { get; set; } = false;
  13.         /// <summary>
  14.         /// 是否对签名数据的参数值进行UrlEncode
  15.         /// </summary>
  16.         public bool IsDoUrlEncodeForSourceValue { get; set; } = false;
  17.         /// <summary>
  18.         /// 签名主体是否包含参数名
  19.         /// </summary>
  20.         public bool IsSignTextContainKey { get; set; } = true;
  21.         /// <summary>
  22.         /// 签名主体中参数和参数值的连接符(需要启用IsSignTextContainKey)
  23.         /// </summary>
  24.         public string SignTextKeyValueSeparator { get; set; } = "=";
  25.         /// <summary>
  26.         /// 签名主体中不同参数项的连接符
  27.         /// </summary>
  28.         public string SignTextItemSeparator { get; set; } = "&";
  29.         /// <summary>
  30.         /// 编码
  31.         /// </summary>
  32.         public Encoding DefaultEncoding { get; set; } = Encoding.UTF8;
  33.     }
  34. }
复制代码
HttpSigner类

签名组件的具体实现。
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. namespace JiuLing.CommonLibs.Security.HttpSign
  5. {
  6.     /// <summary>
  7.     /// 网络请求签名工具
  8.     /// </summary>
  9.     public class HttpSigner
  10.     {
  11.         /// <summary>
  12.         /// 签名配置
  13.         /// </summary>
  14.         private readonly HttpSignSetting _setting = new HttpSignSetting();
  15.         /// <summary>
  16.         /// 最终的签名串
  17.         /// </summary>
  18.         private string _signString;
  19.         /// <summary>
  20.         /// 设置签名数据
  21.         /// </summary>
  22.         /// <param name="signSource">待签名的键值对</param>
  23.         /// <param name="setting">配置签名规则</param>
  24.         /// <returns></returns>
  25.         /// <exception cref="ArgumentException"></exception>
  26.         public HttpSigner SetSignData(Dictionary<string, string> signSource, Action<HttpSignSetting> setting = null)
  27.         {
  28.             setting?.Invoke(_setting);
  29.             if (_setting == null)
  30.             {
  31.                 throw new ArgumentNullException("无效的签名配置", "setting");
  32.             }
  33.             if (signSource == null || signSource.Count == 0)
  34.             {
  35.                 throw new ArgumentException("待签名数据异常", nameof(signSource));
  36.             }
  37.             var signSourceList = new List<HttpSignItem>(signSource.Count);
  38.             foreach (var item in signSource)
  39.             {
  40.                 var itemValue = item.Value;
  41.                 if (_setting.IsDoUrlEncodeForSourceValue)
  42.                 {
  43.                     itemValue = System.Web.HttpUtility.UrlEncode(itemValue, _setting.DefaultEncoding);
  44.                 }
  45.                 signSourceList.Add(new HttpSignItem(item.Key, itemValue));
  46.             }
  47.             if (_setting.IsOrderByWithKey)
  48.             {
  49.                 signSourceList = signSourceList.OrderBy(x => x.Key).ToList();
  50.             }
  51.             if (_setting.IsSignTextContainKey)
  52.             {
  53.                 _signString = string.Join(_setting.SignTextItemSeparator, signSourceList.Select(x => $"{x.Key}{_setting.SignTextKeyValueSeparator}{x.Value}"));
  54.             }
  55.             else
  56.             {
  57.                 _signString = string.Join(_setting.SignTextItemSeparator, signSourceList.Select(x => x.Value));
  58.             }
  59.             return this;
  60.         }
  61.         /// <summary>
  62.         /// 签名主体设置前缀
  63.         /// </summary>
  64.         /// <param name="input">前缀值</param>
  65.         /// <returns></returns>
  66.         public HttpSigner SetSignTextPrefix(string input)
  67.         {
  68.             _signString = $"{input}{_signString}";
  69.             return this;
  70.         }
  71.         /// <summary>
  72.         /// 签名主体设置后缀
  73.         /// </summary>
  74.         /// <param name="input">后缀值</param>
  75.         /// <returns></returns>
  76.         public HttpSigner SetSignTextSuffix(string input)
  77.         {
  78.             _signString = $"{_signString}{input}";
  79.             return this;
  80.         }
  81.         /// <summary>
  82.         /// 签名主体设置后缀
  83.         /// </summary>
  84.         /// <returns></returns>
  85.         public HttpSigner SetUrlEncode()
  86.         {
  87.             _signString = System.Web.HttpUtility.UrlEncode(_signString, _setting.DefaultEncoding);
  88.             return this;
  89.         }
  90.         /// <summary>
  91.         /// 签名主体进行Base64
  92.         /// </summary>
  93.         /// <returns></returns>
  94.         public HttpSigner SetSignTextBase64()
  95.         {
  96.             _signString = Base64Utils.GetStringValue(_signString);
  97.             return this;
  98.         }
  99.         /// <summary>
  100.         /// 签名主体进行MD5
  101.         /// </summary>
  102.         /// <param name="isToLower">签名结果是否转小写</param>
  103.         /// <returns></returns>
  104.         public HttpSigner SetSignTextMD5(bool isToLower = true)
  105.         {
  106.             if (isToLower)
  107.             {
  108.                 _signString = MD5Utils.GetStringValueToLower(_signString);
  109.             }
  110.             else
  111.             {
  112.                 _signString = MD5Utils.GetStringValueToUpper(_signString);
  113.             }
  114.             return this;
  115.         }
  116.         /// <summary>
  117.         /// 签名主体进行SHA1
  118.         /// </summary>
  119.         /// <param name="isToLower">签名结果是否转小写</param>
  120.         /// <returns></returns>
  121.         public HttpSigner SetSignTextSHA1(bool isToLower = true)
  122.         {
  123.             if (isToLower)
  124.             {
  125.                 _signString = SHA1Utils.GetStringValueToLower(_signString);
  126.             }
  127.             else
  128.             {
  129.                 _signString = SHA1Utils.GetStringValueToUpper(_signString);
  130.             }
  131.             return this;
  132.         }
  133.         /// <summary>
  134.         /// 获取签名结果
  135.         /// </summary>
  136.         /// <returns></returns>
  137.         public string GetSignResult()
  138.         {
  139.             return _signString;
  140.         }
  141.     }
  142. }
复制代码
5、附上仓库地址

以上代码包含在我的通用类库中,可以直接Nuget搜索JiuLing.CommonLibs安装。
GitHub类库地址
文章代码地址

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4