Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django login "?next=" only saving one GET parameter

I'm using Django 1.10 and Python Social Auth 0.1.0.

I use Django login view, having only added the template with:

<a href="{% url 'social:begin' 'azuread-oauth2' %}{% if request.GET.next %}?next={{ request.GET.next }}{% endif %}" class="btn btn-primary btn-lg"><i class="fa fa-windows" aria-hidden="true"></i> {% trans 'Login' %}</a>

This works fine if my ?next= is something like:

  • app/something/
  • app/something/?info=blue

But it doesn't work for:

  • app/something/?info=blue&moreinfo=red

What happens is that the redirect is done to: app/something/?info=blue.

Is there any reason for the redirect to fail for more than one GET parameter? I've tested several times (different apps, and also with Django 1.9 and this happens always).

This is a big problem because I'm building an APIusing Django Rest Framework and Django OAuth Toolkit. Having an API that may use another to log in (two oauth2 in a row) requires several parameters (?client=fasa&....) to be saved in the next variable.

like image 459
NBajanca Avatar asked Oct 24 '25 21:10

NBajanca


2 Answers

In the related question escaping ampersand in url, you will see that there are a selection of reserved characters which include ampersand

 # $ & + ,  / : ; = ? @ [ ]

These characters need to be percent encoded in order to be included/escaped.

Thus your url needs to escape these characters, for example

app/something/?info=blue%26moreinfo=red

You may also be able to use the urlencode function - See How to urlencode a querystring in Python?

>>>import urllib
>>>urllib.urlencode({'next': 'app/something/?info=blue&moreinfo=red'})
'next=app%2Fsomething%2F%3Finfo%3Dblue%26moreinfo%3Dred'

For templates, django has the urlencode template tag, which eventually uses pythons built in urllib to achieve the same thing as the above python code

{{ request.GET.next|urlencode }}
like image 147
Sayse Avatar answered Oct 27 '25 11:10

Sayse


The problem, as stated by @Sayse, is related to the encoding of the URL.

In Django, this is already taken care of. And so making the call app/something/?info=blue&moreinfo=redand redirected to login, as:

myapp.com/login?=next=app/something/%3Finfo=blue%26moreinfo=red

This happens since Django methods login_required and LoginRequiredMixin already encodes the URL. This is great because ìt makes {{ request.GET.next }} recognize as next the complete redirect URL.

The problem is then in {{ request.GET.next }} that "unencodes the URL".

The problem is solved with urlencode, doing {{ request.GET.next|urlencode }}:

<a href="{% url 'social:begin' 'azuread-oauth2' %}{% if request.GET.next %}?next={{ request.GET.next|urlencode }}{% endif %}" class="btn btn-primary btn-lg"><i class="fa fa-windows" aria-hidden="true"></i> {% trans 'Login' %}</a>
like image 29
NBajanca Avatar answered Oct 27 '25 12:10

NBajanca



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!