2017-04-03 70 views
1

我有一个在安全的Nginx服务器上运行的django rest框架应用程序。 当我在DRF api上导航时,导航栏中的协议很好地重定向到https。 我的问题是,所有生成的网址都在http而不是https中。 我在代码的注视下,型动物网址是建立与这种方法:无法激活与Django和Nginx的HTTPS链接

def build_absolute_uri(self, location=None): 
     """ 
     Build an absolute URI from the location and the variables available in 
     this request. If no ``location`` is specified, bulid the absolute URI 
     using request.get_full_path(). If the location is absolute, convert it 
     to an RFC 3987 compliant URI and return it. If location is relative or 
     is scheme-relative (i.e., ``//example.com/``), urljoin() it to a base 
     URL constructed from the request variables. 
     """ 
     if location is None: 
      # Make it an absolute url (but schemeless and domainless) for the 
      # edge case that the path starts with '//'. 
      location = '//%s' % self.get_full_path() 
     bits = urlsplit(location) 
     if not (bits.scheme and bits.netloc): 
      current_uri = '{scheme}://{host}{path}'.format(scheme=self.scheme, 
                  host=self.get_host(), 
                  path=self.path) 
      # Join the constructed URL with the provided location, which will 
      # allow the provided ``location`` to apply query strings to the 
      # base path as well as override the host, if it begins with // 
      location = urljoin(current_uri, location) 
     return iri_to_uri(location) 

在我而言,这个方法总是返回不安全的网址(http而不是HTTPS)。 我编辑了我在本文中描述的设置: https://security.stackexchange.com/questions/8964/trying-to-make-a-django-based-site-use-https-only-not-sure-if-its-secure 但是生成的url仍然是HTTP。 这里是我的Nginx的配置:

server { 
     listen 80; 
     listen [::]:80; 

     server_name backend.domaine.na.me www.backend.domaine.na.me server_ip:8800; 

     return 301 https://$server_name$request_uri; 
} 

server { 
     # SSL configuration 

     listen 443 ssl http2; 
     listen [::]:443 ssl http2; 
     include snippets/ssl-backend.domaine.na.me.conf; 
     include snippets/ssl-params.conf; 

     location/{ 
       proxy_pass http://server_ip:8800/; 
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
       proxy_set_header X-Forwarded-Proto https; 
       proxy_set_header Host $http_host; 
       proxy_redirect off; 
     } 
} 


server { 
     listen 8800; 
     server_name server_ip; 
     location = /favicon.ico { access_log off; log_not_found off; } 

     location /static/ { 
       root /projects/my_django_app; 
     } 

     location /media/ { 
       root /projects/my_django_app; 
     } 

     location/{ 
       include proxy_params; 
       proxy_pass http://unix:/projects/my_django_app.sock; 
     } 

     location ~ /.well-known { 
       allow all; 
     } 
} 

我的Django的配置:

wsgi.py

os.environ['HTTPS'] = "on" 
os.environ['wsgi.url_scheme'] = "https" 

settings.py(注:我都试过前两行)

#SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') 
SECURE_PROXY_SSL_HEADER = ('HTTP_X_SCHEME', 'https') 
SESSION_COOKIE_SECURE = True 
CSRF_COOKIE_SECURE = True 

我真的需要修复这个问题,因为我的DRF API会返回一些图片URL,必须在HTTPS中,否则该网站不能被视为100%安全。

我的配置有什么问题?我错过了一些选择吗?

回答

1

间接是不需要的;您可以合并从SSL块和设置:8800块给这样的事情:

server { 
     listen 80; 
     listen [::]:80; 

     server_name backend.domaine.na.me www.backend.domaine.na.me; 

     return 301 https://$server_name$request_uri; 
} 

server { 
     # SSL configuration 

     listen 443 ssl http2; 
     listen [::]:443 ssl http2; 
     include snippets/ssl-backend.domaine.na.me.conf; 
     include snippets/ssl-params.conf; 

     location = /favicon.ico { access_log off; log_not_found off; } 

     location /static/ { 
       root /projects/my_django_app; 
     } 

     location /media/ { 
       root /projects/my_django_app; 
     } 

     location ~ /.well-known { 
       allow all; 
     } 

     location/{ 
       proxy_pass http://unix:/projects/my_django_app.sock; 
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
       proxy_set_header X-Forwarded-Proto https; 
       proxy_set_header Host $http_host; 
       proxy_redirect off; 
     } 
} 

然后,设置SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https'),它应该工作。

我找不到关于include proxy_params的任何信息,我怀疑你在第一个代理块中设置的头文件根本没有被转发到Django应用程序。