LoginSignup
0
1

More than 1 year has passed since last update.

DRFでセッション認証

Posted at

概要

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

カスタムユーザーを作成します。

session_auth/account/models.py
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を編集します。

session_auth/project/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を編集します。

session_auth/account/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/を開き、管理画面にアクセスします。

Screen Shot 2023-02-21 at 20.34.09.png

先ほど作成した、スーパーユーザーアカウント情報で、ログインします。

Screen Shot 2023-02-21 at 20.34.22.png

Sessionsを確認すると、1つセッションが作成されていることを確認できます。

Screen Shot 2023-02-21 at 20.35.08.png

確認ができましたら、一度ログアウトしておきましょう。

続いて、serializers.pyを作成します。

session_auth/account/serializers.py
from rest_framework import serializers
from .models import User


class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = "__all__"

views.pyを編集します。

session_auth/account/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を更新します。

session_auth/account/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))
]
session_auth/project/urls.py
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にアクセスしてみましょう。

以下のように、エラーがでたら正しくセッション認証が設定されています。
session-auth-1.png

続いて、セッションを作成するため、管理画面にログインしてみましょう。
Sessionsを確認すると、セッションが作成されていますね。
session-auth-2.png

この状態で再度http://127.0.0.1:8000/api/v1/accountにアクセスしてみます。
session-auth-3.png

ユーザー情報が取得できました!😊

以上で、DRFのセッション認証の実装方法の解説を終わります。

ありがとうございました!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1