when I get an object in django rest framework the urls always come absolute with localhost, but in production im going through a proxy on nginx, is there a way to set this url in the settings
Example
count: 11
next: "http://localhost:8000/api/accounts/?ordering=-date_registered&page=2"
previous: null
I need it to be
count: 11
next: "http:/example.com/api/accounts/?ordering=-date_registered&page=2"
previous: null
---------- edit --------------------------
please see my complete nginx config
server {
listen 80;
server_name 123.123.123.123;
root /home/admin/www/site-web/dist;
index index.html;
charset utf-8;
location /static/ {
alias /home/admin/www/site/static/;
}
location /media/ {
alias /home/admin/www/site/media/;
}
location /nginx_status/ {
# Turn on nginx stats
stub_status on;
# I do not need logs for stats
access_log off;
# Security: Only allow access from 192.168.1.100 IP #
# allow 192.168.1.100;
# Send rest of the world to /dev/null #
# deny all;
}
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
try_files $uri $uri/ /index.html;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
#
# Om nom nom cookies
#
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
}
location /docs/ {
proxy_pass http://127.0.0.1:8000/docs/;
break;
}
location /api/ {
underscores_in_headers on;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://127.0.0.1:8000/api/;
break;
}
location /admin/ {
proxy_pass http://127.0.0.1:8000/admin/;
break;
}
}
==== super edit====
================
Set USE_X_FORWARDED_HOST
in your settings to True
and make sure you pass it along using your web server(proxy) as well.
When django does build_absolute_uri()
it calls get_host()
- see below in django.http.request:
def get_host(self):
"""Returns the HTTP host using the environment or request headers."""
# We try three options, in order of decreasing preference.
if settings.USE_X_FORWARDED_HOST and (
'HTTP_X_FORWARDED_HOST' in self.META):
host = self.META['HTTP_X_FORWARDED_HOST']
...
See Real life usage of the X-Forwarded-Host header?
It sounds like your Host
header is not being set properly, which would be an issue in your nginx configuration. The issue is that your Host
header that is being sent includes the port number, so Django is including the port number when building out urls. This will cause future issues with CSRF, because CSRF checks do strict port checking when you are not debugging.
This is known to cause issues with SSL for similar reasons.
You can fix this by setting the Host
header within Nginx to not include the proxied port.
proxy_set_header Host $http_host;
Note that I used the $http_host
variable instead of $host
or $host:$server_port
. This will ensure that Django will still respect CSRF requests on non-standard ports, while still giving you the correct absolute urls.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With