Note: originally posted on StackOverflow but seems like it may be worth opening an issue, since the functionality might be here but, at the very least, the documentation is missing.
I need to pass data through a social authentication (so I can access it after the login is complete) using django-allauth, but I'm not sure how to go about doing this as the documentation seems to be completely lacking in this area.
From what I gather, OAuth2 accepts a state parameter that can be used to transfer this sort of data. After spending hours trolling through the django-allauth code, it appears that there might be some ability to append a dynamic state parameter. However, I have no idea what the proper way to introduce this data into the request is, nor at what point this should occur. Do I need to monkey patch something in socialaccounts/views.py? Unfortunately it doesn't seems like the socialaccounts adapter.py has any way to hook into a request like this.
Edit: It looks like there's also some opportunity to access the state parameter here, but again, I'm unsure of the best way to do this.
Be aware that the state parameter content ends up being visible in the URL, so why not put the information you want to preserve in the session?
After working with this over the last week, I did indeed discover that I could pass data through the social login process by hijacking auth_params and using JavaScript to append "&auth_params=foo" to the URL just before attempting the social login. This brilliantly stored the data in the session, as you mentioned, allowing it to emerge safely on the other side. However, I still have the following concerns:
auth_params and fill it with my own data I want to pass through? It was my understanding (from the naming convention and a few random notes in the documentation) that auth_params is to be used specifically for supplying parameters used as part of the authorization process.It indeed was not intended for this . Why not simply store the data you want to preserve in request.session -- so forget about the allauth handshake details completely?
I'd love to do this, and I did some research on the topic, but there don't appear to be any signals or adapter methods I can hook into (where I can access and modify request.session) that are called before leaving the page for /accounts/(socialnetwork)/login.
Is the only alternative to make a separate view that modifies the session, then redirects to the appropriate social network login? Isn't it inefficient to do it this way, since it seems like the machinery is already in place in allauth? If you can't tell yet, I'm an ignorant neophyte barely hacking my way through everything. :(
I would need more insight into your exact use case to say something sensible about this. It seems to me that if you were able to fill the session just before doing the social provider handshake, then the data you would like to store is not depending on user input or anything? What kind of data is this, when is this typically created?
Normally, I would expect that (user inputted data) to be the case, e.g. you click around on the site, perhaps choose in a signup form between 2 different account types or subscription plans, and store that information in the session.
Happy to oblige. I'm passing two things:
Edit: It seems I can handle 2 in the same view used to process the AJAX post, but I'm still unclear on how to add 1 to the session the moment the "Sign in with (socialnetwork)" button is pressed. Is the best solution here to take the long route and have that button do an AJAX post to yet another view that updates the session, then have the callback go through the allauth social login motions?
The social login URLs support passing next parameters, see next:
<a href="{% provider_login_url "openid" openid="https://www.google.com/accounts/o8/id" next="/success/url/" %}">Google</a>
That can be used to solve 1). You solved 2) yourself...
Right, I'm already taking advantage of the next parameter for the post-callback redirect.
However, what I'm trying to do here is keep track of the page that the user was looking at when they decided to sign up for an account. request.META['HTTP_REFERER'] is unreliable in this case because the user is likely being redirected from a social networking site when the callback is triggered and registration is completed.
Thanks for verifying that what I outlined for number 2 is the best way forward.
Would something like this work?:
Sorry, I guess I left out a couple details that are probably important in this case:
{% provider_login_url "facebook" method="oauth2" %}What I was originally asking for was a way to pass parameters through provider_login_url so I can access them once the user finishes logging into the social network and gets directed back via the callback.
The hacky way that I'm currently passing the origin page through is by using a bit of JS when the user clicks on the button to add something like "&auth_params=" + encodeURIComponent("origin_page=" + window.location.href) to the provider_login_url, and then grabbing origin_page from the auth_params once they're retrieved from the session state at the end.
That will work, but I feel your pain. :) As an alternative, you could also set a cookie client-side and handle process that server-side later on ..
Thanks for all your feedback on this! I mainly wanted to verify that I wasn't overlooking some functionality that already existed in allauth. I think I'll go the :cookie: route so I'm not using auth_params in a way that wasn't intended.
Most helpful comment
The social login URLs support passing next parameters, see
next:That can be used to solve 1). You solved 2) yourself...