Masonite Framework makes authentication more simple. You can add a default authentication boilerplate (register, login, reset password, logout) with craft auth command. That’s pretty nice.

But sometimes, in your application, you want to allow the user to register/sign in via GitHub, Facebook, Twitter, Google, etc.

In this article, I’ll show you how to implement GitHub authentication in a Masonite application using masonite-socialite. Masonite-socialite package supports several other providers and the process is the same.

Create new Masonite application

# Create a new folder
mkdir app

# Move into that folder
cd app

# Create a new virtual environment
virtualenv -p python3 venv

# Activate the virtual environment
source venv/bin/activate

# Install masonite package usign pip
pip install masonite

# Create a new Masonite application in the current directory. Do not forget the dot '.' at the end
craft new app .

Install Masonite Socialite

Install masonite-socialite using pip:

pip install masonite-socialite

Add SocialiteProvider to the providers list in config/providers.py:

from socialite.providers import SocialiteProvider

PROVIDERS = [

    # Third Party Providers
    SocialiteProvider,
]

Run craft socialite:install to publish socialite config file.

Create an authentication workflow

  1. Open http://localhost:8000/ and click on a button;
  2. Redirect to http://localhost:8000/auth/github;
  3. Redirect again to GitHub to login;
  4. Redirect back to http://localhost:8000/auth/github/callback;
  5. Print user’s full name on the page.

cover

Full-size workflow picture

Routes

Clean the routes/web.py file and add the following routes:

"""Web Routes."""

from masonite.routes import Get

ROUTES = [
    Get('/', 'HomeController@index').name('home'),
    Get('auth/github', 'SocialAuthController@login').name('auth.github.login'),
    Get('auth/github/callback', 'SocialAuthController@callback').name('auth.github.callback'),
]

You can use Masonite RouteGroup to share route auth/github part in the routes:

"""Web Routes."""

from masonite.routes import Get, RouteGroup

ROUTES = [
    Get('/', 'HomeController@index').name('home'),
    RouteGroup([
            Get('/', 'SocialAuthController@login').name('login'),
            Get('/callback', 'SocialAuthController@callback').name('callback'),
        ],
        prefix='/auth/github',
        name='auth.github.',
    ),
]

Controllers

Let’s create two controllers:

# Generate HomeController
craft controller Home

# Generate SocialAuthController
craft controller SocialAuth

Cleanup the HomeController.py file and put the following inside:

"""A HomeController Module."""

from masonite.view import View
from masonite.controllers import Controller


class HomeController(Controller):
    """HomeController Controller Class."""

    def index(self, view: View):
        return view.render('home')

This will render a view call home. Create that view. A view is just an HTML file. By running craft view home, you can create a new HTML file called: home.html inside: resources/templates directory;

You’re up to write what you want inside that folder. Import Bootstrap or Tailwind. We only need a link (anchor) that point to auth/github.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Masonite GitHub Authentication</title>
</head>
<body>
    <p>
        <a href="{{ route('auth.github.login') }}">
            Sign in with GitHub
        </a>
    </p>
</body>
</html>

Step 1 Done ✅

Now, it’s time to open the SocialAuthController file. Put this inside:

"""A SocialAuthController Module."""

from socialite import Socialite
from masonite.controllers import Controller


class SocialAuthController(Controller):
    """SocialAuthController Controller Class."""

    def login(self, socialite: Socialite):
        return socialite.driver('github').redirect()

Get GitHub Credentials

Log in to your GitHub account and go to your settings (top-right dropdown). Select the Developer applications tab and create new application. Enter a name and: - use http://localhost:8000/auth/github as the Authorization callback URL. - use http://localhost:8000/ as the home page URL.

Once you created that application, you’ll have a set of credentials. Open the .env file in your application and take the values from GitHub and put them into the file.

SOCIAL_AUTH_GITHUB_KEY=key-from-github
SOCIAL_AUTH_GITHUB_SECRET=client-secret-from-github
SOCIAL_AUTH_GITHUB_REDIRECT_URI=http://127.0.0.1:8000/auth/github/callback

Step 2 Done ✅

Get the authenticated user details

One thing that is missing right now, is the callback method. Let’s fix it.

"""A SocialAuthController Module."""

from masonite.view import View
from socialite import Socialite
from masonite.request import Request
from masonite.controllers import Controller


class SocialAuthController(Controller):
    """SocialAuthController Controller Class."""

    def login(self, socialite: Socialite):
        return socialite.driver('github').redirect()

    def callback(self, view: View, request: Request, socialite: Socialite):
        user = socialite.driver('github').user()
        fullname = user.fullname

        return view.render('home', {'fullname': fullname})

Step 3 Done ✅

This line socialite.driver('github').user() retrieve the user details from GitHub. Now, we can show the user full name in home.html view.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Masonite GitHub Authentication</title>
</head>
<body>
    <p>
        {% if fullname %}
            <h2>Hello, {{ fullname }}</h2>
        {% else %}
            <a href="{{ route('auth.github.login') }}">
                Sign in with GitHub
            </a>
        {% endif %}
    </p>
</body>
</html>

Step 4 Done ✅

Users can now sign up with various social providers: Twitter, Facebook, Github, LinkedIn, Google and many others. Under the hood, masonite-socialite uses Python Social Auth - Core package which support several backends.

Don’t forget to subscribe to our bi-monthly newsletter 📨