Python Django 入門トップページ


Django REST Framework による API 開発

  1. API とプロジェクトの概要
  2. Django REST Frameworkのインストール
  3. プロジェクトの作成
  4. 基本設定
  5. アプリケーションの作成と登録
  6. モデルの作成とマイグレーション
  7. テストデータの設定
  8. コメント一覧を出力する API
  9. コメント詳細情報を出力する API
  10. 新規投稿と更新・削除の API
  11. ページネーション
  12. 入力内容の検証(バリデーション)
  13. テストの自動化
  14. Shell でのユーザ登録
  15. Fixtures でのユーザ登録
  16. ユーザ認証を必須にする
  17. コメントにオーナ情報を追加
  18. 権限の設定:Case #1
  19. 権限の設定:Case #2
  20. Python から API への接続
  21. React アプリケーションからの API 接続と CORS エラーの回避

Django REST Framework による API 開発

ユーザ認証を必須にする

現時点でユーザ認証ができるようになりましたが,ユーザ名を指定しなければ全ての操作ができる状態にありました.ここでは,閲覧だけでなく投稿や更新など全ての操作でユーザ認証を求めるようにします.

Django REST Framework の permissions を利用するとさまざまなアクセスに対して許可や拒否を設定することができます.例えば,次の通り IsAuthenticated を指定すると,そのクラスの実行時にはユーザ認証を求めることができます.

comments\views.py
from django.shortcuts import render
from rest_framework import generics
from rest_framework import permissions
from .models import Comment
from .serializers import CommentSerializer
from .paginations import LargeResultsSetPagination

# Create your views here.

class CommentList(generics.ListCreateAPIView):
    queryset = Comment.objects.all()
    serializer_class = CommentSerializer
    pagination_class = LargeResultsSetPagination
    permission_classes = [permissions.IsAuthenticated]

class CommentDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Comment.objects.all()
    serializer_class = CommentSerializer
    permission_classes = [permissions.IsAuthenticated]

実際に認証が必要になっているかどうかを GET メソッドについて確認すると,正しいユーザ名とパスワードを与えたときだけ閲覧が許可されていることがわかります.

...\django_comment_api>curl http://127.0.0.1:8000/comments/ ⏎
{"detail":"認証情報が含まれていません。"}
...\django_comment_api>curl http://127.0.0.1:8000/comments/1/ ⏎
{"detail":"認証情報が含まれていません。"}
...\django_comment_api>curl -u user_a:password http://127.0.0.1:8000/comments/ ⏎
{"count":11,"next":"http://127.0.0.1:8000/comments/?page=2","previous":null,"results":[{"id":13,"title":"0123456789","body":"012345678901234","updated_at":"2023-11-23T15:24:38.905335"},{"id":9,"title":"9個目のコメント","body":"コメントの本 文9","updated_at":"2023-11-23T11:20:00"}]}
...\django_comment_api>curl -u user_a:password http://127.0.0.1:8000/comments/1/ ⏎
{"id":1,"title":"最初のコメント","body":"コメントの本文","updated_at":"2023-11-23T11:01:00"}
...\django_comment_api>curl -u user_a:abc http://127.0.0.1:8000/comments/ ⏎
{"detail":"ユーザ名かパスワードが違います。"}
...\django_comment_api>curl -u user_a:abc http://127.0.0.1:8000/comments/1/ ⏎
{"detail":"ユーザ名かパスワードが違います。"}
...\django_comment_api>

次に POST メソッドでも確認すると期待した結果になりました.

...\django_comment_api>curl -X POST -d "title=auth" -d "body=required" http://127.0.0.1:8000/comments/ ⏎
{"detail":"認証情報が含まれていません。"}
...\django_comment_api>curl -X POST -d "title=auth" -d "body=required" -u user_a:password http://127.0.0.1:8000/comments/ ⏎
{"id":14,"title":"auth","body":"required","updated_at":"2023-11-23T16:22:51.508782"}
...\django_comment_api>

さらに Web ブラウザでも表示すると,ログインしていないために期待通りに 403 エラーが表示されました.

django-api-2023-17

上の画面ではログインのメニューが表示されていないので,ログイン操作ができるようにプロジェクトの urls.py に次のブロックを追加します.

django_comment_api\urls.py(抜粋)
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path("admin/", admin.site.urls),
    path('', include('comments.urls')),
]

# 次のブロックを追加すると,ブラウザで閲覧した時,右上にログインのメニューが現れる
urlpatterns += [
    path('api-auth/', include('rest_framework.urls')),
]

もう一度一覧ページを読み込み直すと再び 403 エラーですが,右上に Log in メニューが表示されました.このメニューをクリックします.

django-api-2023-18

美しくデザインされたログインページが表示されました.

django-api-2023-19

ユーザ名とパスワードを入力してログインします.

django-api-2023-20

無事に一覧ページを閲覧できました.

django-api-2023-21

もちろん詳細表示も可能です.

django-api-2023-22

ログインすることで,一覧表示や個別表示ができるようなりました.次のページではコメントを誰が投稿したのか,その情報を管理できるようにします.

目次に戻る