单位的 HIS 系统需要增加一个上报接口,his 商部署后一直调试有问题,对端平台返回报错“非法参数"。
联系平台技术人员确认 token 、appid,secret 都没有问题。his 商找不到问题,就说平台那边的问题,搞成无限循环了。
无奈研究接口文档,用蹩脚的编程水平通过 python 自己调用接口,发现平台是可以成功返回正常信息的,确认平台正常。让 his 找自己的问题,结果最后发现是 his 商将 secret 的一个 0 写成了 o ,问题解决。
一个低级错误,卡了几天,我觉得一方面是自己水平不够高,没仔细看接口文档,第二方面平台返回的信息比较少,另一方面是 his 商自己测试不严谨造成的,都有问题。

🤣遇到这种情况确实很糟心,几个长得很像的字符,乍一看真认不出来

用特殊字体,一看就能区分出 0 个 o

secret 应该很长吧? his 商手动抄上去的?

或许是从截图里面 OCR 上去的

对这种低级错误早没脾气了。

不长,怀疑是手动。没太深究了,错误太低级。

何必为了别人的错误发脾气,一笑带过。多想想自己也有没做好的地方。

这时候专业的编程字体就能起到一定的提示作用,数字 0 中间有斜杠或点,o 就是 o

都是好建议,有没有推荐的字体?

有没有推荐的字体?NerdFont 都是不得不吐嘈一下 Chrome 地址栏中 I(大写的 i) l(小写的 L) 分不清每次我在手机上获得百度网盘的分享链接, 里面往往有 l 和 I,在地址栏直接输入导致我 404

0oil1I , 有些字体显示的这几个是真容易看错

0Oil1I 小米字体还可以,这个完全的靠字体。

八成是从微信的拍屏中拷过来的。

另一种改进思路是生成随机 secret 的时候就不用 oO0iIl1 这些字符

核对字符串不能靠看,只能搜

根本是对端平台智障的错误提示…这不应该是 401 之类的未认证错误么

secret 错了他们自己咋调试通的?

想起来前几天和你这个何其相似 后台配置页面 secret 后面多了一个空格。白瞎好几天

《论编程字体选择的重要性》

字体推荐:Oxygen Mono

说明文档写的不够好。

secret 错误, 不应该很容易从日志里看出来吗

secret 错误返回非法参数? 那从日志看是哪一行报非法参数应该也能找出来

手抄 secret 啊 至少 32 位呢

有可能是 PDF 复制过去的

HIS 是医院的系统, 多半是跟公网隔离的, 所以手抄 secret 也不奇怪, 抄错也不奇怪. 受限制的环境下工作就是比较麻烦

对端平台返回报错“非法参数"对端平台也是二把刀,不应该返回 forbidden 或者 unauthorized ,外加一个自定义错误码吗?

我在工作中也遇到过类似的,几个人找了好几个小时,发现是一个变量 o 被写成了 0 。

一直用 console 字体,感觉还行吧...

其实是平台报错有歧义,非法参数到底是 token 、secret 验证失败,还是请求 api 的参数有问题? 我认为做接口一定要报错报清楚了,什么参数有问题就说哪个参数有问题,并且给出解决方案是最好的报错。 譬如这边如果报错提示“验签失败,请检查 token 、appid 、secret”。 如果是上报的某个参数真的有问题,举个例子如果是 age 参数,后台校验 age 必须为 int ,且必须 0-100 之间,既然校验这里报错了,就应该提示“age 参数非法,请输入 0-100 之间的数字”。怕就怕接口文档不写清楚,报错提示也不模模糊糊,这种接口最难对了

想起了那个用户昵称就叫 “Null” 的了。

οver , over这是我之前在 v2 看到的一个帖子,上面这两个 over 说实话我用肉眼真的分不清

补全错了,是 Consolas

bug 的真正含义

#32 我的天.....这是什么啊

所以说有的字体很傻逼

Operator Mono

o 和 l 应该被开除字母集

微信中的大写 i 和小写 L

这两个神奇的 o

Source Code Pro 还不错,一直在用0Oil1I 这几个区别还比较明显 github.com/adobe-fonts/source-code-pro

Consolas 对 O0o Ww Uu Ss Kk Zz Xx Cc Vv 的识别并不是很好,至少没有对比的情况下,Oo 和 Ww 是真的一眼看不出来

Jetbrain 的字体也挺好的,这些长得差不多的字母都有区别。

这还是平台问题, 没对密码做模糊验证处理. 比如 o, 0, O, 这种都要看作同一个字符视为验证通过.

来回顾一下快 4 年的这个贴吧 www.hesudu.com/t/638609针对 Java static int i = Integer.parseInt(SomeUtil.readNumberFromPropeties);然后在 Propeties 里面写了 2O 不是 20Integer.parseInt("2O")会抛出 java.lang.ExceptionInitializerError .. Caused by: java.lang.NumberFormatException ...然后这个 java.lang.ExceptionInitializerError 不能被 catch(Exception e) 捕获,没有记录日志应该 catch(Thrwoable e) 捕获,才能记录下日志然后你的同学,坚持了所谓的异常处理"军规",Never catch Throwable class……导致没有任何出错日志,此问题异常难查XD

常年都是在编辑器里看的,大小写这个还好认一点,只能要能区分出 0oli 就行(笑哭

所以成熟接口验证算法里有防呆机制,会通过算法中的特殊设置去掉这类的识别干扰项

这些密钥啥的应该都是复制的, 或者直接写在配置文件里, 需要时候读取, 不应该放代码里一起吧

确实经验还不够,这种 bug 在正常水平开发者手里应该活不过 2 小时,像这类平台类参数错误第一反应不是应该对比同参数签名的结果值是否一致么,逐一排除干扰因素一下就找到问题了