【问题标题】:nginx location and Django authnginx 位置和 Django 身份验证
【发布时间】:2018-03-07 09:21:52
【问题描述】:

我正在尝试根据查询字符串中的 URL 参数创建 NGINX 重定向。基本上有:

http://localhost/redirect/?url=https://www.google.it/search?dcr=0&source=hp&q=django&oq=django

location /redirect/ {
    proxy_cache STATIC;
    # cache status code 200 responses for 10 minutes
    proxy_cache_valid 200 1d;
    proxy_cache_revalidate on;
    proxy_cache_min_uses 3;
    # use the cache if there's a error on app server or it's updating from another request
    proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
    # don't let two requests try to populate the cache at the same time
    proxy_cache_lock on;

    # Strip out query param "timestamp"
    if ($args ~ (.*)&timestamp=[^&]*(.*)) {
      set $args $1$2;
    }

    return 302 $arg_url$args;
}

现在,只有经过 Django 身份验证的用户 (JWT/Cookie) 可以使用/redirect?url= 端点,因此是否可以在不向全世界打开代理的情况下实现会话/cookie 检查?

无论如何,我可以在 Django 级别 (https://github.com/mjumbewu/django-proxy/blob/master/proxy/views.py) 做到这一点,但我认为在 NGINX 级别它更快且计算成本更低。

谢谢,

D

【问题讨论】:

标签: django nginx nginx-location


【解决方案1】:

根据之前的答案(谢谢!)这是解决方案:

http {
    upstream app_api {
    # server 172.69.0.10:8000;
    server api:8000;
    # fail_timeout=0 means we always retry an upstream even if it failed
    # to return a good HTTP response (in case the Unicorn master nukes a
    # single worker for timing out).
    # server unix:/var/www/gmb/run/gunicorn.sock fail_timeout=0;
  }

server {

    location = /auth {
      proxy_pass http://app_api/api-auth/login/;
      proxy_pass_request_body off;
      proxy_set_header Content-Length "";
      proxy_set_header X-Original-URI $request_uri;
    }

    location /redirect/ {
      auth_request /auth;

      proxy_cache STATIC;

      # cache status code 200 responses for 10 minutes
      proxy_cache_valid 200 1d;
      proxy_cache_revalidate on;
      proxy_cache_min_uses 3;
      # use the cache if there's a error on app server or it's updating from another request
      proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
      # don't let two requests try to populate the cache at the same time
      proxy_cache_lock on;

      # Strip out query param "timestamp"
      if ($args ~ (.*)&timestamp=[^&]*(.*)) {
        set $args $1$2;
      }
      return 302 $arg_url$args;
    }

【讨论】:

    【解决方案2】:

    重定向和代理是不同的东西,要获得 django-proxy 功能,您需要使用 nginx 反向代理选项而不是重定向。

    # django-proxy code fragment
    response = requests.request(request.method, url, **requests_args)
    proxy_response = HttpResponse(
            response.content,
            status=response.status_code)
    

    用于反向代理和身份验证的 Nginx 配置

    server {
        listen 80;
        server_name youtdomain.com;
    
        location / {
            # use django for authenticating request
            auth_request /django-app/;
            # a proxy to otherdomain
            proxy_pass http://otherdomain.com;
            proxy_set_header Host otherdomain.com;
        }
    
        location /django-app/{
            internal; # protect from public access
            proxy_pass http://django-app;
        }
    }
    

    Django 应用程序应该为经过身份验证的用户返回 200 状态代码 401 否则,您可以阅读有关 auth_request here 的更多详细信息

    【讨论】:

    • 基本上来自网站的只有经过身份验证的用户使用 Django Rest Framework (DRF) 应该使用 NGINX 位置 /redirect/?url= 但不使用 NGINX 反向代理,否则我可以创建一个 DRF 端点。答案是'auth_request'
    • 请注意,您提到的django-proxy 不是重定向,而是下载内容并传递给客户端,其行为类似于 nginx 反向代理
    猜你喜欢
    • 1970-01-01
    • 2021-08-21
    • 1970-01-01
    • 2013-01-24
    • 2014-08-27
    • 2012-01-01
    • 1970-01-01
    • 2021-02-18
    • 2013-11-03
    相关资源
    最近更新 更多