选择对 API 请求的正确响应有助于保护应用程序,并能够提高项目开发效率。虽然表面上看起来可能并非如此,但每一条不必要的信息都使攻击者更容易了解如何获得访问权限。另一方面,每一个缺失的信息都会让 API 的使用者更难理解对 HTTP 请求的响应。
本文将介绍用于 API 安全目的(登录或者鉴权)的常见的 HTTP 错误响应码。通常当请求成功时,这意味着:
- 请求令牌唯一正确标识用户
- 请求中的资源存在
- 对资源的操作有效
- 用户对该资源的该操作具有必要的权限
对于成功响应的请求返回状态码:2XX
,否则对于上面的情况有三个相关的错误代码:401
、403
、404
。
401
401 ,表示请求需要用户认证信息,因为它缺少目标资源的有效身份验证凭据。用户未经过身份验证,API 需要有效用户,这由请求中的 Authorization
标头确定。下面是 401 正常使用的情况:
- 没有指定令牌
- 指定的令牌格式无效
- 令牌已过期
- 在极少数情况下,令牌有效,但不应用于此 API
403
403,表示服务器理解请求但拒绝授权,与 401 不同的是,客户端的身份是服务器已知的,只是用户未被授权,用户尝试执行操作,但标识用户的令牌没有足够的权限来执行此操作,常用于提示用户缺少相应的权限,如 Google 403 的响应界面如下:
404
404,表示服务器找不到请求的资源,导致 404 页面的链接通常被称为损坏或死链接,并且可能会受到链接失效的影响。如果 url 路径(也称为资源)不存在,则 404 是更合适。
错误代码的选择
看起类很容易选择,在大多数情况下,它们有一定顺序的:
- 验证令牌
- 验证用户权限
- 检查资源是否存在
有时 2
和 3
的顺序可以对换,具体取决于应用程序服务器。但是,如果这样做的话,很容易导致资源被暴露,因为验证资源有效性是发生在鉴权之前,意味着没有权限也可以验证资源是否存在。
如果用户无权访问资源并且该资源存在,常规是返回 403 更合理,资源不存在则返回 404 。
在常规情况下,如果无法访问资源,将根据该资源是否存在返回不同的信息。未经许可的用户可以开始扫描所有端点和潜在资源,以搜索现有端点。
相反,建议应该将 403 分解为更细微的类别。如果用户知道某个资源但没有权限,则返回 403。但是,用户不关心资源是否存在,而缺失权限的提醒对于用户来说也没什么意思,在这种情况下统一返回 404 。
那么什么情况下使用 403 呢?
对于一些内容系统或者平台,可以按照状态码的精确用意处理。
总结
API 的设计离不开状态码的部分,而鉴权是一个系统常见的功能,以确保系统的安全。有时候为了安全,鉴权相关的错误码没必要精确提供,越精确的错误某种意义上增加了安全风险。