概要
PythonのDjango REST Framweorkで、セッション認証を実装する方法を手順を交えて紹介します。
セッション認証とは?
セッション認証とは、Webアプリケーションにおいて、ユーザーがログインした状態を管理する認証の一つです。セッション認証では、ユーザーがログインすると、サーバー側でセッションを作成し、そのセッションにログイン情報を保存します。その後、セッションの有効期限が切れるまで、ユーザーがリクエストを送信するたびに、そのリクエストに含まれるセッションIDを使用して、サーバー側でセッションオブジェクトを特定し、ユーザーがログイン済みかどうかを確認します。
Django REST Frameworkでのセッション認証の方法
各種バージョン
Python: 3.10
Django: 4.1.4
Docker: 20.10.11
docker-compose: 2.2.1
手順
Djangoの基本環境構築
Qiitaのこちらの記事の「仮想環境構築」および、「Djangoプロジェクト作成」欄を参照ください。
今回、プロジェクト名はsession_auth
とします。
セッション認証の実装手順
ユーザー情報を管理するアプリを作成します。
(venv) session_auth % python manage.py startapp account
カスタムユーザーを作成します。
from django.db import models
from django.contrib.auth.models import (BaseUserManager,
AbstractBaseUser,
PermissionsMixin)
from django.utils.translation import gettext_lazy as _
class UserManager(BaseUserManager):
def _create_user(self, email, username, password, **extra_fields):
email = self.normalize_email(email)
user = self.model(email=email, username=username, **extra_fields)
user.set_password(password)
user.save(using=self._db)
user.full_clean()
return user
def create_user(self, email, username, password=None, **extra_fields):
extra_fields.setdefault('is_active', True)
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
return self._create_user(
email=email,
username=username,
password=password,
**extra_fields,
)
def create_superuser(self, email, username, password, **extra_fields):
extra_fields['is_active'] = True
extra_fields['is_staff'] = True
extra_fields['is_superuser'] = True
return self._create_user(
email=email,
username=username,
password=password,
**extra_fields,
)
class User(AbstractBaseUser, PermissionsMixin):
username = models.CharField(
verbose_name=_("username"),
unique=True,
max_length=150
)
email = models.EmailField(
verbose_name=_("Email Address"),
unique=True
)
age = models.IntegerField(
verbose_name=_("age"),
null=True,
blank=True
)
is_superuser = models.BooleanField(
verbose_name=_("is_superuer"),
default=False
)
is_staff = models.BooleanField(
_('staff status'),
default=False,
)
is_active = models.BooleanField(
_('active'),
default=True,
)
objects = UserManager()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email']
def __str__(self):
return self.username
settings.pyを編集します。
...
ALLOWED_HOSTS = ["*"] # ワイルドカードを追加
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework', # djangorestframeworkを追加
'account' # 作成したaccountアプリを追加
]
...
AUTH_USER_MODEL = "account.User" # accountアプリのUserモデルをデフォルトで使用する認証ユーザーモデルとして設定する
...
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # セッションを何で保存するかを指定する。この場合はDBで管理する。
セッションを管理画面で確認できるよう、admin.pyを編集します。
from django.contrib import admin
from django.contrib.sessions.models import Session
admin.site.register(Session)
ここまでできましたら、マイグレートします。
(venv) session_auth % python manage.py makemigrations
(venv) session_auth % python manage.py migrate
ここで、スーパーユーザーを作成し、管理画面にログインできることを確認します。
(venv) session_auth % python manage.py createsuperuser
Username (leave blank to use 'testuser'): testuser
Email address: test@example.com
Password:
Password (again):
Superuser created successfully.
開発用サーバーを起動します。
(venv) session_auth % python manage.py runserver
ブラウザでhttp://127.0.0.1:8000/admin/を開き、管理画面にアクセスします。
先ほど作成した、スーパーユーザーアカウント情報で、ログインします。
Sessionsを確認すると、1つセッションが作成されていることを確認できます。
確認ができましたら、一度ログアウトしておきましょう。
続いて、serializers.pyを作成します。
from rest_framework import serializers
from .models import User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = "__all__"
views.pyを編集します。
from rest_framework import viewsets
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from .models import User
from .serializers import UserSerializer
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
authentication_classes = (SessionAuthentication,)
permission_classes = (IsAuthenticated, )
UserViewSetのauthentication_classesにSessionAuthenticationを、
permission_classesにIsAuthenticatedを設定します。
これで、UserViewsSetへアクセスするには、セッション認証が必須となります。
ちなみに、viewsets.ModelViewSetとは、一覧取得、詳細取得、新規作成、更新、削除のViewをまとめて管理してくれる非常に便利なビューです。
(今回は認証の確認のため一覧取得の機能しか使いません。)
UserViewSetへアクセスできるようにするため、urls.pyを作成し、project/urls.pyを更新します。
from django.urls import include, path
from rest_framework.routers import DefaultRouter
from .views import UserViewSet
router = DefaultRouter()
router.register(r'account', UserViewSet)
urlpatterns = [
path('', include(router.urls))
]
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/', include('account.urls')), # account/urls.pyを指定
]
これで、/api/v1/accountにアクセスすると、セッション認証が実行され、認証が通ると、ユーザー情報を取得できるようになっているはずです!
動作確認
確認してみましょう!
まずは、http://127.0.0.1:8000/api/v1/accountにアクセスしてみましょう。
以下のように、エラーがでたら正しくセッション認証が設定されています。
続いて、セッションを作成するため、管理画面にログインしてみましょう。
Sessionsを確認すると、セッションが作成されていますね。
この状態で再度http://127.0.0.1:8000/api/v1/accountにアクセスしてみます。
ユーザー情報が取得できました!😊
以上で、DRFのセッション認証の実装方法の解説を終わります。
ありがとうございました!