java开源 - 云代码空间
——
提示睡眠的时候,群里反馈订单接收失败,工排查问题,日志验签失败,发现异常写作的错误,总算有一个错误
次的属于同类场景的api,对根据常见的本数据库进行的收款处理到,签名规则的顺序和后续参数的升序,然后进行后续的串串、后续的串连、追踪上秘或按照指定的加密方式生成签名
设计之初,肯定是怎么简单怎么来,粗略代码变成
[httppost] public async task<iactionresult> testsendorder([frombody] receiveorderrequest request) { var secret_key = _options.value.secretkey; var url = _options.value.host; //1.将模型转成json格式字符串 var param = jsonconvert.serializeobject(request); //2.将json格式字符串,序列化成有序字典 sorteddictionary<string, string> dict = jsonconvert.deserializeobject<sorteddictionary<string, string>>(param); //3.循环字典,按规则拼接成待加密的明文字符串 var data = ""; foreach (var item in dict) { if (item.key == "sign") continue; data += $"{item.key}={item.value}&"; } data += $"secret_key={secret_key}"; //4.生成签名 var sign = encrypthelper.sha1encryption(data); request.sign = sign; //5.模拟订单推送 var res = await _httpclienthelper.postdata(url, jsonconvert.serializeobject(request)); return ok(res); }意外意外肯定是要出意外的时候,发现json联有待出加密的明文类型,有问题顺序出列,这里有两个
1. datetime格式不一致 如: datetime dt = "2022-07-30 12:26:56" 序列化后 dt=2022-07-30t12:26:56 2. decimal小数点后自动补0 如: decimal price = 10 序列化后 price=10.0针对第一个问题,很好,我们按照顺序化的时间,指定日期时间的格式可以解决
var iso = new isodatetimeconverter(); iso.datetimeformat = "yyyy-mm-dd hh:mm:ss"; var param = jsonconvert.serializeobject(request, iso);
针对个别的问题,起来就比较了,用作业要处理的一些东西(主要不会),这不符合“简单”的定义,麻烦换个方案
通过反射出现与对象的值,然后将结果丢到查找值里面,我写了一个来判断值是否是类型,则方法名称,
public string getfmortdatetime(string strdate) { datetime dt; if (datetime.tryparse(strdate, out dt)) { return dt.tostring("yyyy-mm-dd hh:mm:ss"); } else { return strdate; } }
不出意外,肯定是要出意外的,也不会有这个意外去水的博客了
9.9,结果个的的的是是是是结果被2022-09-0900:00:00:00:00,吃吃惊惊,看来,看来看来看来看来是把数字成月份月份了,真就很简单了,因为定义了数据模型,我们直接在的时候发现问题,获取该值的类型,做自动判断问题
public static async task<bool> checksign(dynamic request, string secret) { sorteddictionary<string, string> dict = new sorteddictionary<string, string>(); foreach (propertyinfo p in request.gettype().getproperties()) { var value = p.getvalue(request); if (value == null) { dict[p.name] = ""; } else { var valuetype = value.gettype(); if (valuetype.name == "datetime") { dict[p.name] = convert.todatetime(value).tostring("yyyy-mm-dd hh:mm:ss"); } else { dict[p.name] = value.tostring(); } } } var sign = dict["sign"]; dict.remove("sign"); var data = ""; foreach (var item in dict) { data += $"{item.key}={item.value}&"; } data += $"secret_key={secret}"; var new_sign = encrypthelper.sha1encryption(data); return new_sign.tolower() == sign.tolower(); }
看到这里,可能有合作伙伴要分开了,你这一个,通过循环定义了两次加密的“待加密字符串,不符合”,干脆直接用一个简单的脚本模型字典去接收参数就好了,这样只用一次循环
秒啊,秒秒,妙蛙种子都没有啊,这种做法不是啊,你后面不过这么维护的人估计要狂抓了,按照规矩约,我们是不这么推荐干的,这次就破了干一次,另一种问题,一个字符串,如何判断它是一个我们约定的时间格式,很显然9.9不同的时间格式
这里推荐日期时间。具体方法,可以根据我们自定义的方式,来时间解析,舒坦了...
public static string getfmortdatetime(string strdate) { string[] format = { "yyyy-mm-ddthh:mm:ss" }; datetime dt; if (datetime.tryparseexact(strdate,format,cultureinfo.invariantculture,datetimestyles.none,out dt)) { return dt.tostring("yyyy-mm-dd hh:mm:ss"); } else { return strdate; } }