设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间23 现在时间23 缓存数据 安全感不是来源于爱,而是偏爱。人只有确定自己是那个例外,才能安心。晚安,好梦。

安全感不是来源于爱,而是偏爱。人只有确定自己是那个例外,才能安心。晚安,好梦。

查看: 991|回复: 0

通用 HTTP 签名组件的另类实现方式

[复制链接]

  离线 

TA的专栏

  • 打卡等级:热心大叔
  • 打卡总天数:224
  • 打卡月天数:0
  • 打卡总奖励:3283
  • 最近打卡:2025-04-14 12:30:20
等级头衔

等級:晓枫资讯-上等兵

在线时间
0 小时

积分成就
威望
0
贡献
406
主题
376
精华
0
金钱
4489
积分
834
注册时间
2023-1-5
最后登录
2025-4-14

发表于 2023-2-12 10:14:05 | 显示全部楼层 |阅读模式

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类库地址
文章代码地址

到此这篇关于通用 HTTP 签名组件的另类实现的文章就介绍到这了,更多相关HTTP 签名组件内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表