Django behind reverse proxy ?next= issue - django

I have deployed a Django application behind an nginx reverse proxy. This proxy handles multiple Django applications
So the main url is for example https://www.example.com
and then I use the reverse proxy to redirect to the specific Django application using subdirectory
for example https://www.example.com/myapp
The problem is that if I logout from myapp and try to access a page that requires login the redirect link is wrong, instead of
https://www.example.com/myapp?next=/mainpage
it gives me
https://www.example.com/?next=/myapp/mainpage
which is wrong since "myapp" cannot listen to requests from https://www.example.com/
Is there any way I can force Django to understand that the default url is https://www.example.com/myapp and not https://www.example.com?
Thanks

Related

django filefield returning localhost-prefixed URL

I'm trying not to specify the full path of the web app in the settings to make it as portable as possible.
However,
with MEDIA_URL="/media/", an URL returned from a Django FileField model is http://localhost/media/....
with MEDIA_URL="//example.com/media/", the URL returned is http://example.com/media/....
But the schema (http/s) and domain (example.com) should match those of the requesting page. How can I do this?
The Django app is served through Nginx in combination with Gunicorn.
It sounds like nginx and Django are not configured to pass and use http host name (e.g. X-Forwarded-Host header). This looks like a good answer - https://stackoverflow.com/a/58044808/6865

Django redirect not working when specifying HTTP or HTTPS

I am not sure why this is happening, but when I specify HTTP or HTTPS as my full URL in a redirect, the part after my domain name is appended to my current domain.
For example: if I redirect to https://www.external_site.com/error/page/hi_there.html it will go to https://www.currentdomain.com/error/hi_there/html
return redirect('https://www.external_site.com/error/page/hi_there.html')
But, when I remove the https: part (but leave the //), the redirect works as expected:
return redirect('//www.external_site.com/error/page/hi_there.html')
I am using Django v 1.11.23 but also tested it on Django 2.
Django runs on Apache on mod_wsgi, and goes through an IIS reverse proxy (the reverse proxy is just a reverse proxy in this instance, no special rules or anything besides to rewrite the external domain to the internal domain.)
I found the issue.
It is related to "IIS reverse rewrite host in response headers" ARR setting. I disabled it by going to "IIS Manager -> Machine or Site (I used Machine so it applies to all sites) -> Application Request Routing Cache -> Server Proxy Settings and uncheck the "Reverse rewrite host in response headers" checkbox“
Now it is working as it should.

Django and React.js Production

When I've added a React to my Django project. It seems to be like everything works.
But if I refresh the page in the browser, I get an error:
I understand that Django is trying to find an appropriate view, but how to make it so that the React?
Currently, your server is catching routes that are meant for React and trying to handle them. You need to configure your routes so that only actual server routes are handled by the server (usually prefixed with "/api/") and all others are handled by React.
Without seeing your urls.py file, I'm assuming you have your base/naked route ("/") go to the React app, which works fine for initial requests (to the home page), but starts to break down when using a link or refreshing the page.
Your routing should basically use the React app in the way that 404 pages are usually used—when no matching routes on the server are found for the request. It's important that you define all other routes above the route to the React app, so that anything that the server knows how to handle is handled by the server, while the rest is passed along to React client.
So your urls should look something like this:
from django.conf.urls import url, include
from django.views.generic import TemplateView
urlpatterns = [
url(r"^api/v1/", include("api_v1.urls", namespace="api_v1")),
url(r"^.*", TemplateView.as_view(template_name="index.html")),
]
Where index.html is that of your React app.
This is commonly an Apache/NGINX (front-end web server) configuration.
You should configure it to serve the same Django view, where you included your React source, for every route used by your React app.
An nginx example:
location ~ ^/your-django-view/?(.*) {
# rewrite ^ index.html;
proxy_pass http://127.0.0.1:8000;
break;
}
127.0.0.1:8000 should be changes with your django host:port.

Django setting root url path for redirects

I have a project with the following components:
a single page backbone application for the web client
a django app for the api
nginx in front to direct requests to backbone and django
In my nginx conf, I direct the requests to django if the path starts with /api ,
otherwise, I serve the files directly (index.html and static files)
This setup works fine, the problem arises when django needs to redirect the url. Say, for instance, I request /api/users , as I have forgotten the trailing slash, django automatically redirects this, but instead of redirecting to /api/users/ , it redirects to /users/ as django does not know that I am hosting it on /api. How can I configure django to handle this redirect correctly?

Django + Angular + Django-allauth

I'm creating a web application using Django as the backend and Angular for the front.
Angular is running on a Yeoman stack on localhost:9000 while Django is running on localhost:8000 and I'm using grunt-contrib-proxy to redirect all the $http calls from angular at /api to the django port. So for example, if Angular asks for localhost:9000/api/hello this will be redirect to localhost:8000/api/helloand django will serve it.
I'm planning to setup Django Rest Framework for serving all the Angular request to the /api path.
So far so good.
Now, I have an already configured and working installation of Django-allauth for making Oauth authentication to third party services. It does work using plain old Django but I have no idea how to make this work in conjunction with Angular.
The only thing that came into mind was serving the allauth views through django rest framework, but what about redirection after authentication? I can't wrap my mind around it.
Is it better to drop this approach and make the Oauth authentication straight from the front (Angular)?
EDIT:
I managed to call the login view from Angular
In grunt-contrib-proxy I've added the account context and rewrite rule:
context: ['/api', '/accounts'],
rewrite: {
'^/api': '/api',
'^/account': '/accounts'
}
I've made an ajax call from angular, asking for the allaluth login view (for example for github): $http.get('/accounts/github/login/?process=login')
The problem is that I get back:
XMLHttpRequest cannot load https://github.com/login/oauth/authorize?scope=&state=BlaBla&redirect…ub%2Flogin%2Fcallback%2F&response_type=code&client_id=BlaBlaBla. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access. (index):1
(The BlaBla was added by me). I think I'm doing something totally wrong
You need to add an
Origin: http://localhost:9000
to the header in the request that angular sends to Django.
Also make sure the server running Django returns an
Access-Control-Allow-Origin: *
see here for more information.