当前位置:  开发笔记 > 编程语言 > 正文

使用Nginx作为Gunicorn前面的反向代理时,Django应用程序中的REMOTE_ADDR值为空

如何解决《使用Nginx作为Gunicorn前面的反向代理时,Django应用程序中的REMOTE_ADDR值为空》经验,为你挑选了1个好方法。

我已经将nginx设置为反向代理,背景为gunicorn。这个网络服务器设置提供了我的Django应用程序,该应用程序具有一个postgresql后端。整个设置托管在两台Ubuntu计算机上(一个是应用程序计算机,另一个是DB计算机)。

我仅通过gunicorn测试了此设置,没有使用nginx。工作完美。接下来将其投入生产,我在gunicorn前面添加了nginx反向代理。我立即遇到令人沮丧的错误:inet类型的无效输入语法:“”(当用户尝试登录我的Django应用时出现)

登录到我的应用程序的用户的IP地址保存在会话表中;Django自行完成。现在,众所周知的事实是Postgresql要求所有客户端IP都属于INET类(某些其他DB也允许字符串IP,但不允许postgres)。INET类型不允许“”(即空)值,而是为inet类型“”抛出错误的无效输入语法

换句话说,我的nginx反向代理未将其值发送REMOTE_ADDR到Django应用。单独使用gunicorn可以正确设置该值(因此一切正常)。我如何让nginx 在Django的request.META中将$remote_addr值传递REMOTE_ADDR给?

我已经尝试proto_set_header REMOTE_ADDR $remote_addr;location/ etc / nginx / sites-avaialble / myproject文件中的块中添加该文件。它不起作用- HTTP_REMOTE_ADDR稍后我可以在request.META中看到一个值,但REMOTE_ADDR仍为''。

那么,如何在Django的request.META中设置REMOTE_ADDR(即客户端的IP地址)字段?也许我可以通过gunicorn明确地传递它?有人提到我应该在数据库端处理它-我不确定该怎么做?我应该编辑pg_hba.conf还是postgresql.conf之类的东西吗?我已经查看了这些文件,没有选项可以记录“允许IP的空值”。而且,我宁愿将$ remote_addr中的任何值传递给Django,而不是让所有已登录用户的IP为空。

而且不要忘了,如果我使用gunicorn,那么在Django的请求中,REMOTE_ADDR就会正确设置。所以我的猜测是问题出在我如何通过nginx传递它。

请帮忙!如果需要,可以随时询问更多信息。


/ etc / nginx / sites-available / myproject:

server {
    listen 80;
    server_name example.cloudapp.net;
    charset utf-8;
    underscores_in_headers on;
    location = /favicon.ico { access_log off; log_not_found off; }

    location /static/ {

        root /home/mhb11/folder/myproject;
    }

    location / {
        proxy_pass_request_headers on;
        include proxy_params;
        proxy_pass          http://unix:/home/mhb11/folder/myproject/myproject.sock;
    }


    error_page 500 502 503 504 /500.html;
    location = /500.html {
        root /home/mhb11/folder/myproject/templates/;
   }
}

/ etc / nginx / proxy_params:

proxy_set_header Host $host;
proxy_set_header User-Agent $http_user_agent;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE_ADDR $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

小智.. 6

这是一个已知的问题。查看有关运行域套接字服务器时REMOTE_ADDR无效的讨论:https : //github.com/python-web-sig/wsgi-ng/issues/11

确保所有依赖关系保持不变的一件事是编写中间件,该中间件可以在Django项目级别解决您的问题。

例如,如下所示:

class XForwardedForMiddleware():
    def process_request(self, request):
        if request.META.has_key("HTTP_X_FORWARDED_FOR"):
            request.META["HTTP_X_PROXY_REMOTE_ADDR"] = request.META["REMOTE_ADDR"]
            parts = request.META["HTTP_X_FORWARDED_FOR"].split(",", 1)
            request.META["REMOTE_ADDR"] = parts[0]

(来源)

尝试一下,肯定可以解决您的问题。



1> 小智..:

这是一个已知的问题。查看有关运行域套接字服务器时REMOTE_ADDR无效的讨论:https : //github.com/python-web-sig/wsgi-ng/issues/11

确保所有依赖关系保持不变的一件事是编写中间件,该中间件可以在Django项目级别解决您的问题。

例如,如下所示:

class XForwardedForMiddleware():
    def process_request(self, request):
        if request.META.has_key("HTTP_X_FORWARDED_FOR"):
            request.META["HTTP_X_PROXY_REMOTE_ADDR"] = request.META["REMOTE_ADDR"]
            parts = request.META["HTTP_X_FORWARDED_FOR"].split(",", 1)
            request.META["REMOTE_ADDR"] = parts[0]

(来源)

尝试一下,肯定可以解决您的问题。

推荐阅读
跟我搞对象吧
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有