In order to obtain token to access out Django backend using Facebook Social Login we need to do the following:
In order to set up the app follow steps from this amazing tutorial on django_core
In order to make it work you need email address from Facebook, otherwise Django will throw an error due to registering issues (email required).
SOCIAL_AUTH_FACEBOOK_KEY = 'YOUR_FACEBOOK_APP_ID'
SOCIAL_AUTH_FACEBOOK_SECRET = 'YOUR_APPS_SECRET_KEY'
# IMPORTANT! :
SOCIAL_AUTH_FACEBOOK_SCOPE = ['email']
SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = {
'fields': 'email'
}
# djoser/facebook.py
from social_core.backends.facebook import FacebookOAuth2
class CustomFacebookOAuth2(FacebookOAuth2):
REDIRECT_STATE = False
AUTHENTICATION_BACKENDS = (
# Important for accessing admin with django_social
# 'social_core.backends.google.GoogleOAuth2',
'core.restconf.djoser.facebook.CustomFacebookOAuth2',
'django.contrib.auth.backends.ModelBackend',
)
# where your DJOSER settings are
DJOSER = {
# "LOGIN_FIELD": "email",
# 'SEND_ACTIVATION_EMAIL': False,
'SOCIAL_AUTH_ALLOWED_REDIRECT_URIS': [
'http://localhost:8000/temporary-redirect-for-testing/',
]
}
# main/settings.py
# I made my URLs custom:
urlpatterns = [
# ...
path('api/auth/social/', include('djoser.social.urls')),
# This is URL we will use for future testing in pt. 5
# path('temporary-redirect-for-testing/', RedirectSocial.as_view()),
]
This will give us 2 endpoints to test:
GET http://localhost:8000/api/auth/social/o/facebook/?redirect_uri=http://localhost:8000/temporary-redirect-for-testing/
that returns us URL we have to enter in a browser: (note api version that you can customize via social_core settings SOCIALSAUTHFACEBOOKAPIVERSION - that is optional)
{
"authorization_url": "https://www.facebook.com/v3.2/dialog/oauth?client_id=YOUR_FACEBOOK_APP_ID&redirect_uri=http://localhost:8000/temporary-redirect-for-testing/&state=THIS_IS_GENERATED_BY_DJANGOf&return_scopes=true&scope=email"
}
and
POST http://localhost:8000/api/auth/social/o/facebook/
This one requires 2 parameters:
code
state
both we obtain after calling redirect_uri from first call and giving Facebook credentials for any Facebook user.
Important to remember that this call has to be of:
Content-Type: application/x-www-form-urlencoded
Calling this endpoint with a code and state will work only for the first time. Every next time renders:
{
"non_field_errors": ["Authentication process canceled"]
}
But successful call gives us:
{
"access": "eyJ0eXAiOiJK...",
"refresh": "eyJ0eXAiOiJ...",
"user": "FACEBOOK_USER_WE_LOGGED_WITH@gmail.com"
}
This is where a Testing endpoint would come in handy. We need the redirect view that will be called by facebook after executing authorization_url
Let´s create the view that will show us the code and state returned by facebook:
# core/restconf/djoser/views.py
from django.http import JsonResponse
from django.views import View
class RedirectSocial(View):
def get(self, request, *args, **kwargs):
code, state = str(request.GET['code']), str(request.GET['state'])
json_obj = {'code': code, 'state': state}
print(json_obj)
return JsonResponse(json_obj)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
print(context)
return context
Let’s add it to urls.py
# main/settings.py
# Import it from wherever you create the view.
from core.restconf.djoser.views import RedirectSocial
# I made my URLs custom:
urlpatterns = [
# ...
path('api/auth/social/', include('djoser.social.urls')),
path('temporary-redirect-for-testing/', RedirectSocial.as_view()),
]
Now, the final test:
🎉🎉🥳🥳 You did it!
Now you can use your code and state to call the POST url. It can be done from your Django app (if you are not using JS frameworks) or it can be called from your Front End ap using e.g. axios or fetch
var myHeaders = new Headers()
myHeaders.append('Content-Type', 'application/x-www-form-urlencoded')
myHeaders.append('Cookie', 'sessionid=m4c2oc0ahj7dibomn4a2d8uo8wmjrcy0')
var urlencoded = new URLSearchParams()
urlencoded.append('code', 'YOUR_CODE_OBTAINED_FROM_REDIRECT')
urlencoded.append('state', 'YOUR_STATE_OBTAINED_FROM_REDIRECT')
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: urlencoded,
redirect: 'follow',
}
fetch('http://localhost:8000/api/auth/social/o/facebook/', requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.log('error', error))
Dont’t forget to change redirect urls for front-end app
Did you make any mistakes when using this tutorial or you’ve seen one here? Tell me about your insights. Leave a comment with YOUR opinion or QUESTION.