
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;
}
}