To locally test the ability to login in my django
app with Facebook through python-social-auth
, I have followed these steps:
127.0.0.1
to www.florian.com
in /etc/hosts
http://www.florian.com:8000/login/facebook
and http://www.florian.com:8000/complete/facebook
in the field OAuth valid URI redirect
in Facebook Login --> settingspython manage.py runserver www.florian.com:8000
However, when accessing http://www.florian.com:8000/login/facebook
, I get the following error:
Can't Load URL: The domain of this URL isn't included in the app's domains. To be able to load this URL, add all domains and subdomains of your app to the App Domains field in your app settings.
However when I check the validity of this URL with the field available in the Facebook Login --> settings, it is OK.
Here are my Django files:
urls.py:
from django.conf.urls import url, include
from django.contrib import admin
from rest_framework import routers
from backend import views
from webapp import views as webapp_views
from django.contrib.auth import views as auth_views
router = routers.SimpleRouter()
router.register(r'users', views.UserViewSet, 'User')
router.register(r'games', views.GameViewSet, 'Game')
urlpatterns = [
url(r'^$', webapp_views.home, name='home'),
url('', include('social_django.urls', namespace='social')),
# FACEBOOK login/registration from Web
url(r'^login/$', auth_views.login, name='login'),
url(r'^logout/$', auth_views.logout, name='logout'),
url('', include('social_django.urls', namespace='social')),
url(r'^test/', webapp_views.test),
url(r'^admin/', admin.site.urls),
url(r'^connect/', views.CustomObtainAuthToken.as_view()),
url(r'^membership_create/', views.MembershipCreate.as_view()),
# Facebook login/registration from REST API
url(r'^auth/connect_with_fb/', views.ConvertTokenViewWithData.as_view()),
# standard Django login/registration from REST API
url(r'^auth/connect_with_credentials/', views.TokenViewWithData.as_view()),
url(r'^debug/', views.UserLoginAndIdView.as_view()),
url(r'^auth/', include('rest_framework_social_oauth2.urls'),
)
]
urlpatterns += router.urls
login.html
{% block content %}
<h2>Login</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
</form>
<br>
<p><strong>-- OR --</strong></p>
<a href="{% url 'social:begin' 'facebook' %}">Login with Facebook</a>
{% endblock %}
settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework.authtoken',
'rest_framework',
'oauth2_provider',
'social_django',
'rest_framework_social_oauth2',
'backend',
'webapp',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'social_django.middleware.SocialAuthExceptionMiddleware', # <--
]
ROOT_URLCONF = 'WMC.urls'
SOCIAL_AUTH_URL_NAMESPACE = 'social'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [ os.path.join(BASE_DIR, 'templates'),
os.path.join(BASE_DIR, 'webapp/templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'social_django.context_processors.backends',
'social_django.context_processors.login_redirect',
],
},
},
]
WSGI_APPLICATION = 'WMC.wsgi.application'
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
'rest_framework_social_oauth2.authentication.SocialAuthentication',
),
}
AUTHENTICATION_BACKENDS = (
# Facebook OAuth2
'social_core.backends.facebook.FacebookAppOAuth2',
'social_core.backends.facebook.FacebookOAuth2',
# django-rest-framework-social-oauth2
'rest_framework_social_oauth2.backends.DjangoOAuth2',
# Django
'django.contrib.auth.backends.ModelBackend',
)
# Django client_secret for OAuth Toolkit for django-rest-social-auth
CLIENT_SECRET = '***********************************************************************************'
# Facebook configuration
SOCIAL_AUTH_FACEBOOK_KEY = '***********'
SOCIAL_AUTH_FACEBOOK_SECRET = '*****************************'
# Database
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Define SOCIAL_AUTH_FACEBOOK_SCOPE to get extra permissions from facebook. Email is not sent by default, to get it, you must request the email permission:
SOCIAL_AUTH_FACEBOOK_SCOPE = ['email']
SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = {
'fields': 'id, name, email'
}
# Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/
STATIC_URL = '/static/'
Since the 1.6.0
version of the social_core
library (part of python-social-auth
), the field REDIRECT_STATE
of FacebookOAuth2
backend has been set to False
.
As I was using the 1.5.0
version (where REDIRECT_STATE=True
), and as the redirect_state
changes each time in the call to the Facebook login, my app was not able to handle such a dynamic behavior.
Thus, upgrading social_core
to version 1.7.0
solves the issue.