💯
WebAPIに認証機能を追加してみた
はじめに
今回は、以下の記事の続きになります。
また、WebAPIを公開するうえで必要なテスト、公開用ドキュメントも作成しました。
それでは、本題に入ります。
認証機能の追加
Django REST frameworkを使用してトークン認証を実装し、セキュアなAPIを構築します。
1.パッケージのインストール
まず、必要なパッケージをインストールします。
pip install djangorestframework djangorestframework-authtoken
2. 設定ファイルの更新
'settings.py'に以下の設定を追加します。
settings.py
INSTALLED_APPS = [
...
'rest_framework',
'rest_framework.authtoken',
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
3. マイグレーションの実行
トークン認証用のテーブルを作成します。
python manage.py migrate
4. トークン生成エンドポイントの追加
トークンを生成するためのビューとルーティングを追加します。
views.py
# books/views.py
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from rest_framework.response import Response
class CustomAuthToken(ObtainAuthToken):
def post(self, request, *args, **kwargs):
response = super(CustomAuthToken, self).post(request, *args, **kwargs)
token = Token.objects.get(key=response.data['token'])
return Response({'token': token.key})
urls.py
# books/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import BookViewSet, CustomAuthToken
router = DefaultRouter()
router.register(r'books', BookViewSet)
urlpatterns = [
path('', include(router.urls)),
path('api-token-auth/', CustomAuthToken.as_view()),
]
テストの追加
APIのユニットテストを追加して、機能が期待通りに動作することを確認します。
1.テストデータのセットアップ
テスト用のユーザーとトークンを作成し、テストクライアントに設定します。
test_views.py
# books/tests/test_views.py
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APITestCase
from rest_framework.authtoken.models import Token
from django.contrib.auth.models import User
from books.models import Book
class BookAPITest(APITestCase):
def setUp(self):
# テスト用のユーザーを作成
self.user = User.objects.create_user(username='testuser', password='testpassword')
self.token = Token.objects.create(user=self.user)
self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key)
self.book = Book.objects.create(
title="Test Book",
author="Author",
published_year=2023
)
self.url = reverse('book-list')
def test_get_books(self):
response = self.client.get(self.url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(len(response.data), 1)
self.assertEqual(response.data[0]['title'], "Test Book")
def test_create_book(self):
data = {
"title": "New Book",
"author": "New Author",
"published_year": 2024
}
response = self.client.post(self.url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(Book.objects.count(), 2)
self.assertEqual(Book.objects.get(id=response.data['id']).title, "New Book")
2.テストの実行
テストを実行して、すべてのテストが成功することを確認します。
python manage.py test
ドキュメントの作成
Swaggerを使ってAPIのドキュメントを自動生成します。
1.drf-yasgのインストール
'drf-yasg'パッケージをインストールします。
pip install drf-yasg
2.ドキュメントの設定
'settings.py'に'drf_yasg'を追加します。
settings.py
INSTALLED_APPS = [
...
'rest_framework',
'rest_framework.authtoken',
'drf_yasg',
]
3.ルーティングの設定
Swaggerのルートを追加します。
urls.py
# books/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import BookViewSet, CustomAuthToken
from rest_framework.schemas import get_schema_view
from drf_yasg.views import get_schema_view as swagger_get_schema_view
from drf_yasg import openapi
router = DefaultRouter()
router.register(r'books', BookViewSet)
schema_view = swagger_get_schema_view(
openapi.Info(
title="Book Management API",
default_version='v1',
description="API documentation for the Book Management application",
),
public=True,
permission_classes=(permissions.AllowAny,),
)
urlpatterns = [
path('', include(router.urls)),
path('api-token-auth/', CustomAuthToken.as_view()),
path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
]
まとめ
これで、認証機能の実装からテストの追加、ドキュメントの作成までの手順が完了しました。
Discussion