Open DenLilleMand opened 4 years ago
Hello,
Take a look at #491 as for why the DEFAULT_API_URL
is ignored.
In your case, the proxy config might be wrong & thus Django might simply not know it is behind a HTTPS proxy. The issue looks completely unrelated to drf-yasg.
I can't guarantee this would work for you, but I have a similar (working) setup somewhere and a quick look at Django Debug Toolbar tells me that the proxy sets the X-Forwarded-For
and X-Forwarded-Proto
HTTP headers. That might be the solution to your problem, especially the second header !
Hello, Take a look at #491 as for why the
DEFAULT_API_URL
is ignored. In your case, the proxy config might be wrong & thus Django might simply not know it is behind a HTTPS proxy. The issue looks completely unrelated to drf-yasg.
Yes i know that it is unrelated and that my Django doesn't know anything about HTTPs, i have a pretty hardcore setup of NGINX(Ingress K8s) -> NGINX(Docker) -> Gunicorn -> Django, i have tried to set all of the settings about forwarding headers correctly in all of them, but my request tracing is non-existent in my system, so it is hard to know where they get striped if they do.
I can't guarantee this would work for you, but I have a similar (working) setup somewhere and a quick look at Django Debug Toolbar tells me that the proxy sets the
X-Forwarded-For
andX-Forwarded-Proto
HTTP headers. That might be the solution to your problem, especially the second header !
X-Forwarded-For
and X-Forwarded-Proto
is some headers i have been trying to get through to Django including making sure that Django trusts forwarded headers. But i think that the Django Debug Toolbar is a great suggestion for getting some extra info, i had forgotten about that tool.
The reason why i thought to post it here is that i feel like the documentation on this area might be leaking a bit, it could be more clear that the only thing that matters is the Django settings. Ehm.. it is also unclear to me why i cannot just force yasg
to use HTTPs urls just because Django doesn't have it enabled locally. Maybe because it is a dirty way of doing it?
request tracing is non-existent in my system, so it is hard to know where they get striped if they do.
Since everything behind the proxy is HTTP-only, I typically use tcpdump
at various points in the chain. In verbose mode, it prints HTTP requests headers. Something like this:
# tcpdump -nvi <interface name> tcp port http
[ lots of stuff ]
08:43:49.892319 IP (tos 0x0, ttl 64, id 19284, offset 0, flags [DF], proto TCP (6), length 849)
10.0.0.18.42680 > 10.0.0.21.80: Flags [P.], cksum 0x9c5c (correct), seq 1:798, ack 1, win 457, options [nop,nop,TS val 3260241910 ecr 295902270], length 797: HTTP, length: 797
GET /static/favicon.ico HTTP/1.0
Host: the.host.name
X-Forwarded-For: 10.3.0.22
X-Forwarded-Proto: https
Connection: close
[ other headers ]
The reason why i thought to post it here is that i feel like the documentation on this area might be leaking a bit, it could be more clear that the only thing that matters is the Django settings
Since you're the second person to have this issue in a few weeks, I think you're probably right and the documentation could be made clearer on that subject. I'll see if I can come up with a PR when I have some time.
Ehm.. it is also unclear to me why i cannot just force yasg to use HTTPs urls just because Django doesn't have it enabled locally. Maybe because it is a dirty way of doing it?
It's supposed to work transparently whether you're using HTTP or HTTPS, assuming everything is set up properly. So I guess forcing the protocol could be considered "dirty", and should not be necessary.
I'm getting the same error as well. I try endpoints from swagger but mixed content error killed me. Neither, 'DEFAULT_API_URL'
nor USE_X_FORWARDED_HOST = True, SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
worked. I'm stuck on what to do.
I'm getting the same error as well. I try endpoints from swagger but mixed content error killed me. Neither,
'DEFAULT_API_URL'
norUSE_X_FORWARDED_HOST = True, SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
worked. I'm stuck on what to do.
Have you also told any proxies that they have to pass on the headers to Django?
I have this in my nginx config:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
If you use Gunicorn like i do, i can see that there is some options like:
secure_scheme_headers
{'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
and
forwarded_allow_ips = "*"
etc. Clearly mine is not working yet, but i have a feeling that passing on the right headers to Django, will make Django return the absolute URLs in HTTPs instead of HTTP.
I am really not a experienced Django developer, so i was looking at setting the environment variable HTTPS = on
in the WSGI file, but this definitely crashes my server, because i think that it tries to make Django it self run the HTTPs encryption maybe.
Yea, I have tried your nginx settings, nothing worked. I dont get it, it is working fine completely in the demo.
Yea, I have tried your nginx settings, nothing worked. I dont get it, it is working fine completely in the demo.
Arg ok, i'll let you know if i fix it. Hope you'll do the same.
Yea, I have tried your nginx settings, nothing worked. I dont get it, it is working fine completely in the demo.
Arg ok, i'll let you know if i fix it. Hope you'll do the same.
Alright, we have two different Django repos in my company and I had installed drf-yasg to other one and deployed and it worked perfectly! Thus, we can make sure that the problem is not related to drf-yasg but server, nginx etc. This sucks because these DevOps things aren't exactly what I understand. Any help could be perfect.
Hi all
I am running my Django application behind an Apache2 Reverse Proxy and I had the same issue. The following configuration allows me to connect behind the proxy with the original host name and with the "X-Forwarded-Proto"-header set to "https" which drf-yasg considers to generate the base url.
ProxyRequests Off
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
ProxyPass /static/ !
ProxyPass / http://127.0.0.1:8000/
ProxyPassReverse / http://127.0.0.1:8000/
You need to tell Django to trust the X-Forwarded-Proto header that comes from your proxy by setting
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
in your Django settings.py (https://docs.djangoproject.com/en/3.0/ref/settings/#secure-proxy-ssl-header). Please read the attached warning in the documentation.
The interactive part of the API is trying to do HTTP, when my site is running HTTPs.
I think it might be my fault, because my Django instance is only running HTTP between it self and a proxy. I have tried to do environ['HTTPS'] = 'on' but it doesn't quite work, i get 500 errors.
But i don't need Django to generate URLs anyway, relative paths work just fine, but swagger tries to actually do API calls based on them instead of using a relative path.
So I think it could be resolved if the URL argument to
openapi.Info
or putting aDEFAULT_API_URL = "https://example.com/"
would change the HTTP schema being used, but it is just always HTTP regardless of these values. Do you have any suggestions on what to do if those arguments/settings don't work?