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_BACKENDS、SOCIAL_AUTH_AUTH0_*など)やコードは、本記事で解説した内容とほぼ同じように機能します。特別な理由がない限り、新規プロジェクトでは social-auth-app-django の利用を推奨します。
Discussion