问题引入
我们为开发者提供了接口,却对调用者一无所知
假设我们的服务器只能允许 100 个人同时调用接口。如果有攻击者疯狂地请求这个接口,那是很危险的。一方面这可能会损害安全性,另一方面耗尽服务器性能,影响正常用户的使用。
因此我们必须为接口设置保护措施,例如限制每个用户每秒只能调用十次接口,即实施请求频次的限额控制。所以我们必须知道谁在调用接口,并且不能让无权限的人随意调用。
在我们之前开发后端时,我们会进行一些权限检查。例如,当管理员执行删除操作时,后端需要检查这个用户是否为管理员,直接从后端的 session 中获取的。但问题来了,比如我是前端直接发起请求,没有登录操作,没有输入用户名和密码,我怎么去调用呢?
API 签名认证
API 签名认证过程
签发签名 -> 使用签名或校验签名
为什么需要API签名认证
为了保证安全性,不能让任何人都能调用接口。
适用于无需保存登录态的场景。只认签名,不关注用户登录态(为了更通用)。
如何在后端实现签名认证?
需要两个东西,即 accessKey 和 secretKey,来标识用户
和用户名和密码类似,不过每次调用接口都需要带上,实现无状态的请求。
“无状态”指的是每个请求都是独立的,服务器不会保存客户端的任何状态信息。每次请求都包含所有必要的信息来完成该请求。这种设计使得系统更易于扩展和管理。
签发 accessKey 和 secretKey
一般来说,accessKey 和 secretKey 需要尽可能复杂无规律,防止黑客尝试破解,特别是密码。
签名认证实现
通过 http request header 头传递参数。
- 参数 1:accessKey:调用的标识 userA, userB(复杂、无序、无规律)
- 参数 2:secretKey:密钥(复杂、无序、无规律)该参数不能放到请求头中
- 参数 3:用户请求参数
- 参数 4:签名
加密方式:
对称加密、非对称加密、md5 签名(不可解密)
用户参数 + 密钥 => 签名生成算法(MD5、HMac、Sha1) => 不可解密的值
怎么知道这个签名对不对?
服务端用一模一样的参数和算法去生成签名,只要和用户传的的一致,就表示一致。
怎么防重放?
- 参数 5:加 nonce 随机数,只能用一次,(存在问题:服务端要保存使用过的随机数)
所以配合
- 参数 6:加 timestamp 时间戳,校验时间戳是否过期。
API 签名认证是一个很灵活的设计,