403 Forbidden vs 401 Unauthorized HTTP responses

403 Forbidden vs 401 Unauthorized HTTP responses

技术背景

在HTTP请求中,服务器会根据请求的情况返回不同的状态码。其中,401 Unauthorized和403 Forbidden是两个常见的与权限相关的状态码,但它们的含义和使用场景有所不同。正确理解和使用这两个状态码,有助于构建更安全、更友好的Web应用程序。

实现步骤

401 Unauthorized

当服务器返回401状态码时,表示请求需要用户进行身份验证。通常情况下,服务器会在响应中包含一个WWW-Authenticate头字段,用于描述如何进行身份验证。客户端可以重复请求,并在请求头中添加合适的Authorization字段。

403 Forbidden

当服务器返回403状态码时,表示服务器理解请求,但拒绝执行该请求。即使客户端提供了有效的身份验证信息,也无法获得访问权限。通常情况下,重复请求是没有意义的,除非更改了凭证。

核心代码

以下是使用Python的Flask框架示例,展示如何返回401和403状态码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from flask import Flask, request, abort

app = Flask(__name__)

@app.route('/protected')
def protected():
# 模拟检查身份验证
if 'Authorization' not in request.headers:
# 没有提供身份验证信息,返回401
return abort(401)
# 模拟检查授权
if not is_authorized(request.headers['Authorization']):
# 身份验证通过,但没有权限,返回403
return abort(403)
return "You have access to this resource."

def is_authorized(credentials):
# 模拟授权检查逻辑
# 这里可以根据实际情况进行修改
return credentials == 'valid_credentials'

if __name__ == '__main__':
app.run(debug=True)

最佳实践

  • 使用401状态码:当用户没有提供有效的身份验证信息,或者提供的身份验证信息无效时,返回401状态码。这样可以提示用户进行身份验证,并提供相应的验证方式。
  • 使用403状态码:当用户已经进行了身份验证,但没有权限访问请求的资源时,返回403状态码。这样可以明确告知用户,即使重新进行身份验证也无法获得访问权限。
  • 避免信息泄露:在某些情况下,为了避免泄露资源的存在与否,可以使用403或404状态码代替其他状态码。

常见问题

为什么401状态码被称为“Unauthorized”,而实际上应该是“Unauthenticated”?

这是历史遗留问题,在HTTP协议中,401状态码最初被命名为“Unauthorized”,但实际上它表示的是“未进行身份验证”。这可能会导致一些混淆,但现在已经成为了标准的命名。

403状态码是否可以用于未进行身份验证的情况?

从技术上讲,403状态码是401状态码的超集,因此可以用于未进行身份验证的情况。但为了更清晰地表达错误信息,建议在未进行身份验证时使用401状态码,在身份验证通过但没有权限时使用403状态码。


403 Forbidden vs 401 Unauthorized HTTP responses
https://119291.xyz/posts/2025-05-09.403-forbidden-vs-401-unauthorized-http-responses/
作者
ww
发布于
2025年5月9日
许可协议