Authenticate user via Facebook and generate a JWT token via Django Rest Framework

Authenticating via Facebook login for a react native app

·

5 min read

I’m trying to build a server side application that will authenticate users via Facebook for what ever client side apps I want to develop.

I was hoping to be able to simply authenticate users via Facebook from either an iOS/Android React Native app and/or React web app without having to use a ton of other python libraries.

Here are some helpful tutorials/links that helped me achieve this. Thank you!:

Implementing Google Login With JWT in Django for RESTful API Authentication

It’s become common now implementing RESTful API since server can communicate with various devices to communicate each…

medium.com

Manually Build a Login Flow - Facebook Login - Documentation - Facebook for Developers

Implementing Google Login With JWT in Django for RESTful API Authentication

developers.facebook.com

Let’s first set up the Django app

cd projectsmkdir app-login-testcd app-login-testpython -m venv envsource env/bin/activatepip install django djangorestframework djangorestframework-simplejwt

Set the ‘rest_framework’ in settings.py under INSTALLED_APPS as well as add this for authenticating with JWT:

REST_FRAMEWORK = {    "DEFAULT_AUTHENTICATION_CLASSES": [        "rest_framework_simplejwt.authentication.JWTAuthentication",    ],}

Now let’s run server:

python manage.py makemigrationspython manage.py migratepython manage.py runserver

Now let’s set up our developer’s Facebook App

You can se that up here:

https://developers.facebook.com/apps/

  1. Create App -> then create test app by hovering over top right corner

  2. Record the AppID and App Secret from Settings -> Basic

  3. You shouldn’t have to add and URL’s when working on localhost/dev

Now we want to build the login dialog url

This is the link the user will be taken to when the user clicks the Login In Via Facebook button on what ever sign ui screen you create:

https://www.facebook.com/v7.0/dialog/oauth?client_id={app-id}&redirect_uri=http://localhost:8000/login&scope=email--> {app-id} is the app id you recorded from above from your facebook app.
--> scope is the type of permission you want to have access to
--> redirect uri is where you want this login link to be taken to after successful login... in this example we are going to redirect it to our api endpoint /login/Keep this url so that you can use it to login via the web browser

Scope is a comma or space separated list of Permissions to request from the person using your app.

Reference - Facebook Login - Documentation - Facebook for Developers

Each permission has its own set of requirements and usage that are subject to our Platform Policies and your own…

developers.facebook.com

Once successful login Facebook then creates a code which is a long random hash and it’s passed via the redirect uri with the param :

http://localhost:8000/login?code={code-generated-from-above-result}

Now back into Django

# create login app
python manage.py startapp login

In the login app create a views.py with the below:

Add the views into the urls.py in your main app in Django

#1 First go to login screen for facebook:

facebook.com/v7.0/dialog/oauth?client_id={FACEBOOK_APP_ID}&redirect_uri=localhost:8000/login/&state={"{st=state123abc,ds=123456789}"}&scope=email

The above returns code param → then redirects to OUR /login?code={code-generated-from-facebook}

Walking through what the SignInView does

Once the app is redirected to the SignInView /login?code={code-from-facebook-after-success-login} we generate a payload with the required info in order to build the below url and try to grab the user’s access token. We take the code param from the #1 url above.

#2 https://graph.facebook.com/v7.0/oauth/access_token?client_id=1415988338584764&redirect_uri=http://localhost:8000/login/&client_secret={app_secret}&code={code-generated-from-above-result}

URL # 2 is what generates the access token and the response below:

{    “access_token”: “{users_access_token}”,    “token_type”: “bearer”,    “expires_in”: 5181851}

Store the user_access_token for use later on.

We then want to grab our (the developer’s access token in order to make requests to fetch user’s info as well as to inspect/debug the users_access_token to make sure it’s valid). Create payload which will then generate url #3 below.

#3 https://graph.facebook.com/oauth/access_token?client_id={your-app-id}&client_secret={your-app-secret}&grant_type=client_credentials

Here’ is a successful response from the above url:

{    “access_token”: “{developers-app-access-token}”,    “token_type”: “bearer”}

Now inspect the users access token → validate to make sure it’s still valid. Build payload so that we can build and hit the below url #4.

#4 https://graph.facebook.com/debug_token?input_token={token-to-inspect-or-users-access-token}&access_token={app-token-or-admin-token-developer’s-access-token-from-above}

{“data”: {“app_id”: “appid1234567”,“type”: “USER”,“application”: “Example Test App”,“data_access_expires_at”: 1602126624,“expires_at”: 1599532509,“is_valid”: true,“issued_at”: 1594348509,“scopes”: [“public_profile”],“user_id”: “user-id123456”}}

Valid user_access_token ^^^^ and gives us access to the user_id

Now we want to get user info more specifically the email address so that we can create or check if user exists. We can do that by building another payload and hitting the url #5 below. Fields are the user fields you want access to (the permissions you added in the scope way up top!).

#5 https://graph.facebook.com/{user_id}?fields=id,email&access_token={user_access_token}

Then what the view does is checks if there is a user already in our DB with the email address. If not it will generate a new user with that email address and random password.

It then will generate a JWT token using RefreshToken .

And we can pass the response back.

token = RefreshToken.for_user(user) response = {}response["username"] = user.usernameresponse["access_token"] = str(token.access_token)response["refresh_token"] = str(token)

We now have successfully authenticated a user and generated a JWT token that can be returned to any type of client whether that be React-Native or React. Once the client receives that JWT token we want to store that on client side securely and safely. In React-Native i believe the best way to do that is in here:

SecureStore

expo-secure-store provides a way to encrypt and securely store key-value pairs locally on the device. Each Expo project…

docs.expo.io

If you are using Expo.

You can also make your /hello/endpoint require authentication so that you can test if your JWT token is working!

#6 test auth for endpoint

curl -X GET http://localhost:8000/hello/ -H ‘Authorization: Bearer access_token_here’

This is just a test app to get Facebook oauth flow working. Thank you to

Implementing Google Login With JWT in Django for RESTful API Authentication

It’s become common now implementing RESTful API since server can communicate with various devices to communicate each…

medium.com

for helping me see how to do it for Google login!

Next I will be trying to set up React-Native and creating iOS and Android Login Screens that will contain this Facebook login button… and logging in and out users and allowing them to go to a private home screen that requires authentication to view! FYI → Postman was also very helpful in seeing what the facebook graph requests returned!

Django Rest Framework

Facebook