如何在Nginx中使用Proxy_Pass时使用Django请求获取真实的域名

mfpqipee  于 2023-11-17  发布在  Nginx
关注(0)|答案(1)|浏览(150)

我使用docker和nginx来运行我的系统,但我现在遇到了一个问题,我想将我的系统的客户端用户自动重定向到一个子域。即类似prod.example.com的东西。这已经在我的nginx配置中工作,以复制对页面的访问,但我想将特定的client URLMap到子域,而不是主域。
通常这在Django中很简单,使用如下代码:

if not 'prod.' in request.get_host():
    redirect(f'app.{request.get_host()}')
    # example #  get_host()=app | get_absolute_ur()=http://app/, meta: app

字符串
但是我的nginx代理传递使用了一个上游变量,看起来这就是上面尝试的变量所传递的全部内容。我如何才能做到这一点?

upstream app {
    server web:8000; # appserver_ip:ws_port
}

server {
    server_name prod.example.com;
    listen 80;
    client_max_body_size 250M;
    # enforces HSTS or only content from https can be served. We do this in CloudFlare
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header Permissions-Policy "autoplay=(), encrypted-media=(), fullscreen=(), geolocation=(), microphone=(), browsing-topics=(), midi=()" always;

    location / {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_pass http://app;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";

                proxy_redirect off;
                proxy_headers_hash_max_size 512;
                proxy_headers_hash_bucket_size 128;

            }
}

gwo2fgha

gwo2fgha1#

Okay@nigel239通过漂亮的文档链接给了我解决方案。总的来说,我的想法是为每个服务器块->位置传递一个X-Forwarded-Host值到我的NGINX配置:

upstream app {
    server web:8000; # appserver_ip:ws_port
}
server {
    # example.com is main site, prod.example.com is the system
    server_name example.com prod.example.com;
    listen 80;
    client_max_body_size 250M;
    # enforces HSTS or only content from https can be served. We do this in CloudFlare
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header Permissions-Policy "autoplay=(), encrypted-media=(), fullscreen=(), geolocation=(), microphone=(), browsing-topics=(), midi=()" always;

    location / {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Host $host;
                proxy_pass http://app;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";

                proxy_redirect off;
                proxy_headers_hash_max_size 512;
                proxy_headers_hash_bucket_size 128;

            }
}

字符串
然后在settings.py用途:USE_X_FORWARDED_HOST = True
然后在我的中间件中,我可以使用request.META值来获取它:

class RedirectMiddleware(MiddlewareMixin):
    
    def process_request(self, request):
        try:
            session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
            # print('key loaded middleware', session_key)
            # print(request.path, resolve(request.path_info).kwargs)
            kwargs = resolve(request.path_info).kwargs
            if 'client_url' in kwargs:
                client = ClientInformation.objects.filter(url_base=kwargs['client_url']).last()
                if client:
                    # using this to ensure clients go to app....
                    if settings.PROD:
                        if request.META and request.META.get('HTTP_X_FORWARDED_HOST'):
                            # we hold this reference
                            if request.META.get('HTTP_X_FORWARDED_HOST', '') != 'prod.example.com':
                                # redirect
                                proto = 'https' # still passed in but we know what it should be
                                host = 'prod.example.com'
                                path = request.get_full_path()
                                url_to_redirect_to = f'{proto}://{host}{path}'
                                print(url_to_redirect_to)
                                return redirect(url_to_redirect_to, permanent=True)
                            else:
                                pass
                    # print('client url found')
                    request.session = self.SessionStore(session_key)
                    request.client = client

相关问题