Skip to content

Using Django GitHub SSO outside Django Admin

Django GitHub SSO aims for simplicity, that's why the primary focus is on the Admin login logic. But this package can be used outside Django Admin, in a custom login page. To do so, you can follow the steps below.

This is the Tip of the Iceberg

In real-life projects, user customer login involves more than just a login button. You need to implement many features like OTP, Captcha, "Recover Password", "Remember Me", "Login with Passkey" etc. This documentation shows a simple implementation to demonstrate how to use Django GitHub SSO outside Django Admin, but for more complex UX requisites, please check full solutions like django-allauth, or incremental solutions like django-otp, django-recaptcha, django-passkeys, etc.

Add Django GitHub SSO templates to your login page

Inside your login template, just add these two lines:

  • {% include 'github_sso/login_sso.html' %} inside <body>
  • {% static 'django_github_sso/github_button.css' %} inside <head>

Login template example

{% load static %}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Page Login</title>
        <link rel="stylesheet" href="{% static 'django_google_sso/google_button.css' %}">
        <link rel="stylesheet" href="{% static 'django_microsoft_sso/microsoft_button.css' %}">
        <link rel="stylesheet" href="{% static 'django_github_sso/github_button.css' %}">
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.5/dist/css/bootstrap.min.css" rel="stylesheet"
              integrity="sha384-SgOJa3DmI69IUzQ2PVdRZhwQ+dy64/BUtbMJw1MZ8t5HZApcHrRKUc4W0kG879m7" crossorigin="anonymous">
        <style>
            body {
                background-color: #f8f9fa;
            }
            .microsoft-login-btn, .google-login-btn, .github-login-btn {
                padding: 6px 4px;
                height: 36px;
            }
        </style>
    </head>
    <body class="container d-flex flex-column vh-100">
        <div class="d-flex flex-column w-100">
            {% if messages %}
                {% for message in messages %}
                    <div class="alert
                                {% if message.tags == 'error' %}alert-danger{% else %}alert-{{ message.tags }}{% endif %}" role="alert">
                        {{ message }}
                    </div>
                {% endfor %}
            {% endif %}
        </div>
        <div class="d-flex flex-column justify-content-center align-items-center flex-grow-1">
            <div class="card p-4 d-flex align-items-center" style="width: 22rem;">
                <div class="h4">Django GitHub SSO</div>
                {% include 'github_sso/login_sso.html' %}
                <a href="{% url 'admin:index' %}" class="mt-2">Go to Admin</a>
            </div>
        </div>
    </body>
</html>

The include command will add the login button to your template for all django-sso installed in the project.

Define per-request parameters

In the case you need different behavior for the login to Admin and login to Django pages, you can define this using callables on the Django GitHub SSO settings. For example:

Setting Login to Admin Login to Pages
GITHUB_SSO_ALLOWABLE_DOMAINS ["example.com"] ["*"]
GITHUB_SSO_LOGIN_FAILED_URL "admin:login" "index"
GITHUB_SSO_NEXT_URL "admin:index" "secret"
GITHUB_SSO_SESSION_COOKIE_AGE 3600 86400
GITHUB_SSO_STAFF_LIST [...] []
GITHUB_SSO_SUPERUSER_LIST [...] []

You can config almost all settings per request

You can config different GitHub credentials, Scopes, Default Locale, etc. Please check the Settings and Sites docs for more details.

Settings logic example

# settings.py
from django_github_sso.helpers import is_admin_path


def get_sso_config(request):
    config = {
        "admin": {
            "allowable_domains": env.get_or_default("GITHUB_SSO_ALLOWABLE_DOMAINS", []),
            "allowable_orgs": env.get_or_default("GITHUB_SSO_ALLOWABLE_ORGS", []),
            "needed_repos": env.get_or_default("GITHUB_SSO_NEEDED_REPOS", []),
            "allow_all_users": env.get_or_default("GITHUB_SSO_ALLOW_ALL_USERS", False),
            "login_failed_url": "admin:login",
            "next_url": "admin:index",
            "session_cookie_age": 3600,  # 1 hour - default
            "staff_list": env.get_or_default("MICROSOFT_SSO_STAFF_LIST", []),
            "superuser_list": env.get_or_default("MICROSOFT_SSO_SUPERUSER_LIST", []),
            "auto_create_first_superuser": True,  # Create superuser on first eligible user login
        },
        "pages": {
            "allowable_domains": ["*"],
            "allowable_orgs": [],
            "needed_repos": [],
            "allow_all_users": True,
            "login_failed_url": "index",
            "next_url": "secret",
            "session_cookie_age": 86400,  # 24 hours
            "staff_list": [],
            "superuser_list": [],
            "auto_create_first_superuser": False,
        },
    }
    if is_admin_path(request):
        logger.debug("Returning Admin SSO configuration")
        return config["admin"]
    else:
        logger.debug("Returning Pages SSO configuration")
        return config["pages"]


GITHUB_SSO_ALLOWABLE_DOMAINS = lambda request: get_sso_config(request)["allowable_domains"]
GITHUB_SSO_ALLOWABLE_ORGS = lambda request: get_sso_config(request)["allowable_orgs"]
GITHUB_SSO_NEEDED_REPOS = lambda request: get_sso_config(request)["needed_repos"]
GITHUB_SSO_ALLOW_ALL_USERS = lambda request: get_sso_config(request)["allow_all_users"]
GITHUB_SSO_AUTO_CREATE_FIRST_SUPERUSER = lambda request: get_sso_config(request)[
    "auto_create_first_superuser"
]
GITHUB_SSO_NEXT_URL = lambda request: get_sso_config(request)["next_url"]
GITHUB_SSO_LOGIN_FAILED_URL = lambda request: get_sso_config(request)["login_failed_url"]
GITHUB_SSO_SESSION_COOKIE_AGE = lambda request: get_sso_config(request)[
    "session_cookie_age"
]
GITHUB_SSO_STAFF_LIST = lambda request: get_sso_config(request)["staff_list"]
GITHUB_SSO_SUPERUSER_LIST = lambda request: get_sso_config(request)["superuser_list"]

Toggle GitHub SSO between Admin and Page logins

Finally, if you want to toggle between Admin and Page login, you can enable/disable GitHub SSO using the GITHUB_SSO_PAGES_ENABLED and GITHUB_SSO_ADMIN_ENABLED. For example, if you want to enable GitHub SSO only for Page login:

# settings.py

# Enable or disable globally
GITHUB_SSO_ENABLED = True

# Enable or Disable per request
GITHUB_SSO_ADMIN_ENABLED = False
GITHUB_SSO_PAGES_ENABLED = True

How Package knows if the request is for Admin or Page login?

The package uses the is_admin_path and is_page_path helpers to check if the request.path starts with the admin path. To find the admin path, the package uses the SSO_ADMIN_ROUTE setting (default: admin:index).

# settings.py
from django_github_sso.helpers import is_admin_path, is_page_path

SSO_ADMIN_ROUTE = "admin:index"  # Default admin route

GITHUB_SSO_ENABLED = True
GITHUB_SSO_ADMIN_ENABLED = is_admin_path  # Same as True
GITHUB_SSO_PAGES_ENABLED = is_page_path  # Same as True