I'm using python-social-auth with Django to authenticate with Google using Oauth2 (google-oauth2). In my template I use something like:
<a href="{% url "begin:social" "google-oauth2" %}">Login</a>
And it correctly creates an A
element pointing to the correct login url. The thing is, django is running with runserver
option behind Apache with ProxyPass
and ProxyPassReverse
(also tried nginx with proxy_pass
option, not fcgi).
In this scenario I have two problems; first, when creating the authentication request, python-social-auth sends the parameter redirect_uri
as localhost:8000
so I did this on settings.py:
AUTH_EXTRA_ARGUMENTS = {'redirect_uri': 'http://myapp.com'}
And it bypasses the "Bad Request" Google response that is returned if I send localhost:8000
as redirect_uri.
Then, in python-social-auth oauth.py
, here, I can see that
self.auth_complete_params(self.validate_state())
Is sending the same wrong redirect_uri
to Google. So I did something ugly like:
data = self.auth_complete_params(self.validate_state())
data['redirect_uri'] = 'http://myapp.com'
response = self.request_access_token(
self.ACCESS_TOKEN_URL,
data=data, # ugh!
headers=self.auth_headers(),
method=self.ACCESS_TOKEN_METHOD
)
So, that's my current solution. I just don't understand on how to do this on a more elegant way, or the "correct" way.
Any help out there?
Best
If I got that right, the problem is that python-social-auth is creating the wrong redirect_uri to send to the auth provider. It always sends http://localhost:8000/my-login-page
but you want it to send http://myapp.com/my-login-page
.
The right place to specify the redirect URI is in settings.py:
SOCIAL_AUTH_LOGIN_REDIRECT_URL = 'http://myapp.com/my-login-url'
and similar settings for special cases (e.g. SOCIAL_AUTH_NEW_USER_REDIRECT_URL). Then, you need to tell python-social-auth to let you change the domain, otherwise it will force the domain back to localhost:8000
. Do this:
SOCIAL_AUTH_SANITIZE_REDIRECTS = False
(It is also possible to fix this across all of Django by giving hints to its build_absolute_uri()
method about what domain to use. This involves more pieces of your stack but check it out in this answer).
I have Django 1.9 and python-socail-auth 0.2.13
settings.py:
INSTALLED_APPS = [
...
'social.apps.django_app.default',
]
SOCIAL_AUTH_RAISE_EXCEPTIONS = True
RAISE_EXCEPTIONS = True
AUTHENTICATION_BACKENDS = (
'social.backends.google.GoogleOAuth2',
'django.contrib.auth.backends.ModelBackend',
)
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = '***'
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = '***'
SOCIAL_AUTH_PIPELINE = (
'social.pipeline.social_auth.social_details',
'social.pipeline.social_auth.social_uid',
'social.pipeline.social_auth.auth_allowed',
'social.pipeline.social_auth.social_user',
'social.pipeline.user.get_username',
'social.pipeline.social_auth.associate_by_email',
'social.pipeline.user.create_user',
'social.pipeline.social_auth.associate_user',
'social.pipeline.social_auth.load_extra_data',
'social.pipeline.user.user_details',
)
urls.py:
urlpatterns = [
...
url(r'', include('social.apps.django_app.urls', namespace='social')),
url(r'', include('django.contrib.auth.urls', namespace='auth')),
]
In template:
<a href="{% url 'social:begin' 'google-oauth2' %}?next={% url 'dashboard' %}">Google</a> |
Google Developers Console -> App -> Credentials -> OAuth 2.0 client IDs-> Client ID for Web application:
Authorized JavaScript origins:
http://127.0.0.1:8000
Authorized redirect URIs:
http://127.0.0.1:8000
http://127.0.0.1:8000/complete/google-oauth2/