post请求,go源码会把“+”字符转成了空格导致的验签失败问题
问题描述:
安卓7.29的包客户端书城男女图书页面显示异常,冷启动、下拉刷新等都无法恢复,个别用户清除缓存数据后恢复。(说明:安卓从72880开始的包,客户端书城接口升级为v7:/api/v7/book-store,post请求)
问题原因:
线上书城男女图书v7接口part1的 post接口请求,个别手机出现401验签失败。
主要原因为:客户端请求参数里的track_id(值为uid和时间戳的拼接)含有“+”字符,客户端把“+”当成字符串生成了sign值。但是在http协议中“+”就是空格,所以服务端接受到的值是正常的(底层的go源码把+转成了空格),导致生成的sign跟客户端上传的sign不一样,出现验签失败。
疑问点1:为什么v6没有问题,v7有问题?
原因:因为v6接口发现有偶现的401问题,排查到是uid含有”+“导致的,服务端就临时把api/v6/book-store的post接口去掉了参数验签,客户端去掉了无用的uid传参。在后续的需求中,书城接口增加了track_id,值为uid和时间戳的拼接。接口在升级为v7时没有考虑到这个点,服务端接口加有验签,测试设备无uid含有“+“的情况,故而没有及时发现。
疑问点2:为什么只有part1接口有问题,part2接口正常?
原因:track_id字段只在part1接口里有增加,主要用于排行榜的使用。
疑问点3:为什么出现问题的用户,在清除数据后能恢复正常?
原因:查证确认为相同source_uid用户的uid不是唯一的,有在变化,有带“+”的,有不带“+”的。
影响范围:
安卓版本号大于72880,设备获取的uid含有“+”字符的用户。
解决方法:
1、服务端临时把api/v7/book-store的post接口去掉了参数验签(7月31日 17:05已修复上线,用户已恢复正常)
2、推进客户端从根源上解决,uid里面的值最好是解析之后的正常值(重点推进处理,期望下迭代解决)
后续改进:
1、前期发现的问题应该及时推进从根本上解决。
2、服务端针对401验证失败的接口修改监控报警,以便及时发现问题。
说明:
此问题仅对post请求有影响,get请求不需要客户端处理参数encode, 因为get请求默认对参数做了encode。所以get请求不会有401情况。