4

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.

NBajanca
  • 3,544
  • 3
  • 26
  • 53
  • I guess the confusion comes from the fact that the & doesn't know which get it relates to (and must default to the outer most) – Sayse Jan 09 '17 at 18:59
  • 1
    Possible duplicate of [escaping ampersand in url](http://stackoverflow.com/questions/16622504/escaping-ampersand-in-url) – Sayse Jan 09 '17 at 19:21
  • I'll leave my answer for the time being but it appears as though you need to use `%26` and not the html code as I suggest below – Sayse Jan 09 '17 at 19:22
  • I'm testing it, I will comment it shortly – NBajanca Jan 09 '17 at 19:36
  • Glad it worked, I'll delete my answer. I only left it up whilst I wasn't sure if you had read it – Sayse Jan 09 '17 at 19:43
  • 1
    You may answer with ``%26``. I don't think it should be considered a duplicate because I spent at least one hour searching and couldn't find the other question. Because I didn't knew the problem – NBajanca Jan 09 '17 at 19:44

2 Answers2

1

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 }}
Community
  • 1
  • 1
Sayse
  • 42,633
  • 14
  • 77
  • 146
  • Django already does that encoding, the problem continues... I've updated my question, please see if you can help me as I've already accepted the answer. – NBajanca Jan 10 '17 at 09:18
  • @NBajanca - I see, I'll try to see if I can find a better solution than "make a custom template tag" if I get some time to properly look into it. In the mean time, you may unaccept this answer if you wish. – Sayse Jan 10 '17 at 09:23
  • 1
    problem solved with ``{{ request.GET.next|urlencode }}``. I can't believe I spent so much time doing this.... If you want you can update your answer. I will remove the Update when you update the answer as it should be part of it. – NBajanca Jan 10 '17 at 09:29
  • @NBajanca - I've added it to my answer but it feels to me as though it might be better as a self answered question since you were the one that did the research into it and should receive the credit as such :) – Sayse Jan 10 '17 at 09:34
1

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>
Community
  • 1
  • 1
NBajanca
  • 3,544
  • 3
  • 26
  • 53