📝

DjangoでAuth0を使ってみる

に公開

はじめに

DjangoとAuth0を連携させた認証機能の実装方法を解説します。本記事では、python-social-auth[django]ライブラリを利用し、効率的に認証を組み込む手順を具体的に示します。

前提技術スタック

まず、基本となる技術スタックは以下のものです。

  • Django
  • uv
  • Auth0

アプリケーション構築

とりあえず、シンプルに作ってみました。まず、WSL2上に構築した、Ubuntu 24.04の環境を使います。

mkdir ex001
cd ex001
git init
uv init
uv add django python-social-auth[django]

Auth0アカウントでの設定

まず、Auth0ダッシュボードでアプリケーションを作成し、必要な情報を取得します。

Auth0でアプリケーションを作成:

Auth0ダッシュボードにログインし、「Applications」>「Applications」>「Create Application」を選択します。

アプリケーションの種類として「Regular Web Application」を選択し、任意の名前を付けます(例: Django App)。

技術スタックとして「Django」を選択します。

キーの取得:

作成したアプリケーションの「Settings」タブから、以下の情報を取得します。

Domain (例: dev-xxxxxxx.jp.auth0.com)

Client ID

Client Secret

URLの設定:

「Settings」タブで、以下のURLをホワイトリストに登録します(http://localhost:8000は開発環境での例です)。

Allowed Callback URLs (認証後のリダイレクト先):

http://localhost:8000/complete/auth0/

Allowed Logout URLs (ログアウト後のリダイレクト先):

http://localhost:8000/ (または任意のログアウト後のページ)

settings.pyの編集

INSTALLED_APPSに'social_django'を追加します。
また、MIDDLEWAREに'social_django.middleware.SocialAuthExceptionMiddleware'を追加します。

認証バックエンドとして、以下の記述を追加します。

AUTHENTICATION_BACKENDS = (
    'social_core.backends.auth0.Auth0OAuth2',
    'django.contrib.auth.backends.ModelBackend',
)

さらに、Auth0のキーとスコープを設定します。特にスコープを指定しない場合、トークンが不正とみなされエラーが発生します。

注意: 本番環境では、ソースコードに機密情報を直接記述せず、環境変数を使用して設定することを強く推奨します。

SOCIAL_AUTH_AUTH0_KEY = '<Client ID>'
SOCIAL_AUTH_AUTH0_SECRET = '<Client Secret>'
SOCIAL_AUTH_AUTH0_DOMAIN = '<Domain>'
SOCIAL_AUTH_AUTH0_SCOPE = ['openid', 'profile', 'email']

そして、リダイレクトURLを設定します。

LOGIN_URL = '/login-url/'
LOGIN_REDIRECT_URL = '/'
LOGOUT_REDIRECT_URL = '/'

さらに、データベースをマイグレーションします。

uv run manage.py migrate

コード

コードに関しては以下のような形にすれば十分です。

URLルーティングの設定

"""
URL configuration for myproject project.

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/5.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""

from django.contrib import admin
from django.urls import path, include
from myproject import views

urlpatterns = [
    path("admin/", admin.site.urls),
    path("", views.home, name="home"),
    path("", include("social_django.urls", namespace="social")),
    path("logout/", views.logout_view, name="logout")
]

テンプレートの作成

ログイン状態に応じて表示を切り替えるテンプレートを作成します。

{# templates/home.html #}

{% if user.is_authenticated %}
  <p>こんにちは、{{ user.username }}さん。</p>
  <a href="{% url 'logout' %}">ログアウト</a>
{% else %}
  <a href="{% url 'social:begin' 'auth0' %}">Auth0でログイン</a>
{% endif %}

ビューの作成

homeビューとログアウト処理を行うlogout_viewを作成します。

# myproject/views.py

from django.shortcuts import render, redirect
from django.contrib.auth import logout as django_logout
from django.conf import settings
from urllib.parse import urlencode

def home(request):
    return render(request, 'home.html')

def logout_view(request):
    django_logout(request)

    domain = settings.SOCIAL_AUTH_AUTH0_DOMAIN
    client_id = settings.SOCIAL_AUTH_AUTH0_KEY
    return_to = request.build_absolute_uri(settings.LOGOUT_REDIRECT_URL)

    auth0_logout_url = f"https://{domain}/v2/logout?client_id={client_id}&returnTo={return_to}"

    return redirect(auth0_logout_url)

発生しがちなエラー

id_token の欠落、または不正な値

このエラーは、python-social-auth が Auth0 から受け取ったデータ(response)の中にある IDトークンをデコードしようとした際に、その値がJWTとして解釈できる形式になっていないために発生しています。

Auth0がIDトークンを返さない主な理由は、認証リクエスト時に scope パラメーターが不足していることです。

ソースコード中で、スコープを記述しているのはその理由によります。

補足: social-auth-app-djangoへの移行

本記事では python-social-auth[django] を使用しましたが、現在、より一般的に利用され、活発にメンテナンスされている後継ライブラリは social-auth-app-django です。

social-auth-app-django へ移行する場合、必要な主な変更点はライブラリのインストールのみです。

uv add django social-auth-app-django

基本的な設定(AUTHENTICATION_BACKENDSSOCIAL_AUTH_AUTH0_*など)やコードは、本記事で解説した内容とほぼ同じように機能します。特別な理由がない限り、新規プロジェクトでは social-auth-app-django の利用を推奨します。

Discussion