mozilla / django-browserid

Django application for adding BrowserID support.
Mozilla Public License 2.0
180 stars 80 forks source link

Allow {{ request.path }} in browserid_login next parameter. #205

Closed hypertexthero closed 10 years ago

hypertexthero commented 10 years ago

Would be great to somehow allow Django's {{ request.path }} variable to be used in browserid_login's next paramater so that users can be redirected to a destination URL in the address bar such as ?next=/post/ after login.

Basically I'd like to be able to do this:

{% browserid_login text='Login to Post' next='{{ request.path }}' %}
Osmose commented 10 years ago

You can do this now by just using request.path as the parameter for next, without quotes or curly brackets:

{% browserid_login text='Login to Post' next=request.path %}

Make sure that you're using django.core.context_processors.request so that the request is available in the template context, but otherwise this works on my local test site.

Thanks for the report, and feel free to reopen if that doesn't work for you. :)

hypertexthero commented 10 years ago

I've tried the above and it does redirect to the URL, but not to the query string. I.e. When clicking on the login button:

{% browserid_login text='Login to Post' next=request.path %}

while at http://127.0.0.1:8000/accounts/login/?next=/comment/#comment I get redirected to /accounts/login/ and not to /comment/#comment.

I may be doing something wrong in my application (probably!), or haven't understood the Persona login flow properly, but the same thing works with the default Django authentication mechanism — in this case the user is sent to a login form and redirected to the query string to complete the POST action after successful login. Not sure if this is possible? My desired flow is roughly this:

  1. Anonymous user writes a comment and clicks 'Submit Comment'.
  2. User gets redirected to persona login form and logs in.
  3. Comment is posted and user gets redirected to his comment.

Many thanks for your help. I'm excited about Persona and committed to making it work.

Osmose commented 10 years ago

Ah, okay. I understand your flow better now, thanks for the info.

So the next parameter in browserid_login is the URL to redirect to afterwards, so if you wanted to redirect to /comment/#comment after login, you'd do:

{% browserid_login text='Login to Post' next='/comment/#comment' %}

The flow you outlined confuses me a little, because AFAIK you can't start a POST and then do a login with the built-in auth without having some custom code that stores the stuff you POSTed in a session or something until you finish login. Django shouldn't be able to pause mid-POST for auth and then automatically re-trigger it.

For your desired flow, I think you'd have to do something like this:

  1. User writes a comment and clicks 'Submit Comment'.
  2. View saves the comment in an anonymous session or cookie or whatever and redirects to the login page, passing a next param in the URL.
  3. Login form uses request.GET.get('next') as the value for next in browserid_login.
  4. User logs in, gets redirect to next URL.
  5. View takes the comment from the user's session/cookie and writes it to the DB.

An easier flow might be to point users to the login button before they write the comment, and have the next parameter set to request.path so that post-login they come back to the comment form.

What do you think?

hypertexthero commented 10 years ago

I managed to get the redirect working using your strategy of pointing users to the login button before they write the comment, and then redirecting using next='/comment/#comment' — thanks!

I am also using a ratings application built into the Mezzanine CMS which allows users to click on a link to up-vote something. The view code in this application seems to be doing what you describe in your numbered list — save the vote in an anonymous session, redirect to login page, and so on — and this is also working, so, great!

Thanks again!

Osmose commented 10 years ago

No problem, glad you got it figured out! :D