django rest框架在nginx后面但不直接给出403
Posted
技术标签:
【中文标题】django rest框架在nginx后面但不直接给出403【英文标题】:django rest framework gives 403 when behind nginx but not directly 【发布时间】:2013-04-05 04:50:48 【问题描述】:使用 django-rest-framework。在 nginx 后面的生产环境中运行时出现 HTTP 403 错误。当我调用从 APIView 继承以支持 GET 操作的特定视图时,我得到:
"detail": "Invalid username/password"
但是...我只在浏览器中得到这个。当我对同一个 URL 使用 curl 时,我不明白。无论是在 Chrome 和 Firefox 中直接点击 URL,还是通过 AJAX 加载 URL,我都会收到此错误。
如果我先使用管理员帐户通过 Django Admin 登录,我不会收到错误消息。
另外,我只知道这是我从 nginx 后面运行的。如果我使用 Django 开发服务器或 gunicorn 运行,并直接点击端口,我很好,并且可以愉快地匿名点击 URL。如果我把 nginx 放在前面,转发到同一个 gunicorn/runserver 我得到这个错误。
也许这与我的 nginx proxy_pass 设置有关?
location /
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
我正在运行 django rest 框架 2.2.6、Django 1.5 和 nginx 1.2.7。
我在 rest 框架中将限制设置为一个愚蠢的高数字,并查看了默认情况下似乎都打开的权限(但也设置得如此明确)。
谁能指出我正确的方向?
谢谢!
卢多。
【问题讨论】:
您对 django-rest-framework 的身份验证设置是什么? 我只是使用默认值,看起来很合适。 【参考方案1】:当您向网站发送请求时,在基本身份验证之后, 客户端(浏览器)发送“授权”标头(应该 - 请参阅:***上的“基本访问身份验证”)。
Ngnix 将其传递给您的应用程序。
Django Rest Framework 还支持:BasicAuthentication,默认开启。
REST_FRAMEWORK =
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
)
来源:http://www.django-rest-framework.org/api-guide/authentication/
所以 django-rest-framework 看到 'Authorization' 标头,并认为应该是 django 用户的密码。
如果这样的用户不存在,那么你得到:“HTTP 401 Unauthorized”。 见:http://www.django-rest-framework.org/api-guide/authentication/#basicauthentication
解决方案
选择一个: a) 添加到您的 ngnix 站点配置中
location /
...
proxy_set_header Authorization "";
...
所以 DRF 不会得到 'Authorization' 标头,所以它不会尝试匹配 django 用户。
在此更改之后 - 无法在 django 端使用基本身份验证(空头!
b) 从 REST_FRAMEWORK 中删除“rest_framework.authentication.BasicAuthentication”(在您的 django 设置中)。
如果未定义,请添加到您的 django 设置中:
REST_FRAMEWORK =
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
)
可能是最好的解决方案。
c) 使用您的 django 用户/密码进行基本身份验证?
真的吗? - 不要!
【讨论】:
【参考方案2】:如果它是基本的 http 身份验证(如 @Sjoerd 的情况)并且您不需要 django 身份验证,您还可以在 nginx 反向代理配置中删除 Authorization
标头:
location /
...
proxy_set_header Authorization "";
【讨论】:
谢谢!我们刚刚遇到了同样的问题,这有帮助!【参考方案3】:在我的例子中,我在 Apache 中配置了 HTTP 基本身份验证,但在我的 Django 项目中没有。因为请求具有身份验证标头,所以 Django 应用程序认为我想使用它进行身份验证。我使用以下设置禁用了 Django REST 框架中的身份验证:
REST_FRAMEWORK =
'DEFAULT_AUTHENTICATION_CLASSES': []
【讨论】:
谢谢!这正是我的问题 您不需要禁用所有身份验证类,只需删除基本身份验证。在此处查看另一个答案***.com/questions/19693433/… 优秀。这是我使用 VPS + Apache + Passenger (Dreamhost) 时遇到的问题。【参考方案4】:如果您启用了限制,您将收到 403 FORBIDDEN。基于这个问题:https://github.com/tomchristie/django-rest-framework/issues/667,关闭 request.user/request.auth 的惰性评估可能是最好的做法。
【讨论】:
更新到最新版本的 REST 框架应该可以解决这个问题。 (引用的票现已关闭) 嗨。谢谢!不过,我在 2.2.6 上,看起来它包含此修复程序。我正在尝试关注该线程,但看不到禁用节流的简单方法。我确实设置了一个非常高的油门值。也许我应该尝试自定义身份验证类?除非我听到其他情况,否则我想接下来我会尝试。谢谢 我关闭了节流和身份验证,一切都开始工作了。谢谢。以上是关于django rest框架在nginx后面但不直接给出403的主要内容,如果未能解决你的问题,请参考以下文章
我们如何使用基于函数的视图在 django rest 框架中发布数据?
带有 CSRF/CORS 的带有 TokenAuthentication 的 Django REST 框架