简单的api校验
- 服务端维护并提供
ApiKey
ApiSecret
sign=hash(<ApiKey><params><timestamp><ApiSecret>)
方式生成签名,然后将ApiKey和timestamp以及签名放到Header或者Query里传给服务端- 服务端校验header里的时间戳是否太旧,太旧则表示该请求已经过期,需要重新签名
- 服务端根据ApiKey到数据库查询到ApiSecret,按照同样的规则,把客户端传来的时间戳作为时间戳,进行签名,如果签名结果和传过来的签名相同则签名通过,否则401
说明:
- ApiSecret没有在请求中传输,可以保证即使被抓包,也一般不能生成正确的签名(一般来说,怂一点)
- 由于会校验时间戳,那么即使被抓包,那同样的请求并不能再次发送到服务端,因为请求有有效期了,可以一定程度上防止重放攻击(如果客户端和服务端的时间一致,那么可以将过期时间设置的很短)
- 更严格点,可以把签名放到redis,这样一个签名只能请求一次
- 待签名内容需要有参数的部分在内,否则如果请求被拦截,然后篡改请求参数,那也是种攻击
hash+timestamp
- 和前面的类似,只不过时间戳在被签名时不直接拼接,而是使用 timestamp/30,即整除30,那么三十秒内,整除的结果的整数部分是一样的,也就是说30秒内同样的参数,生成的签名是一样的. 例如 1653553144/30 = 55118438.13333333 1653553148/30=55118438.266666666
- 这时候如果客户端和服务端之间有几秒的时间差,那么服务器可以把当前时间戳往前退30秒或者往后推30秒,再整除30,也可以让验证通过