Django REST frameworkのパーミッションのカスタマイズについて
- # Python
- # Django
2020年11月20日
TL;DR
Django REST framework で、ビューへのパーミッションをカスタマイズする方法についてです。
DRF のパーミッション
Django では、 ViewSet
にパーミッションクラスを渡すことでアクセスパーミッションに関する設定をすることができます
例えば、認証済みユーザーに対してのアクセスに制限したい場合は、permissions.IsAuthenticated
クラスを用います
views.py
from rest_framework import viewsets
from rest_framework import permissions
from .models import Sample
from .serializer import SampleSerializer
class SampleViewSet(viewsets.ModelViewSet):
queryset = Sample.objects.all()
serializer_class = SampleSerializer
permission_classes = (permissions.IsAuthenticated, )
これで、各 HTTP メソッドからのアクセスが認証済みユーザーに制限されました
他には標準で,
- AllowAny: だれでも
- IsAuthenticated
- IsAdmin: 管理者アカウントのみ
- IsAuthenticatedOrReadOnly: GET メソッドはだれでも OK だけど、それ以外は認証が必要
などが用意されています
パーミッションクラス
パーミッションクラスには、二種類のメソッドが必要です
メソッド | 対象 |
---|---|
has_permission(request: Request, view: Callable) -> bool | 全ての View |
has_object_permission(request: Request, view: Callable, obj: Model) -> bool | Detail View |
流れとしては、
- リクエストが送られてくる
- 対象のビュー関数に対して、
has_permission()
メソッドをコールして、権限の有無を確認- ない場合 =>
401
- ない場合 =>
- Detail View が対象なら
has_object_permission()
メソッドをコールして、対象のオブジェクトに対して権限があるかを確認- ない場合 =>
403
- ない場合 =>
- レスポンスを返す!
って感じです
カスタマイズする
組み込みのもので要件を満たせない場合は、上記の
has_permission()
has_object_permission()
を定義したパーミッションクラスを用意することで対応できます
カスタマイズの例として, User モデルに対する権限設定を考えます
User モデルに対する CRUD
操作のうち、
- アカウント作成は、アカウントを持っていないユーザーにも提供される
- 閲覧は、認証済みユーザーに制限される
- 更新 & 削除は、認証ユーザーが自身である場合に制限される
と言った形で権限設定をしたい場合は、以下のように実装できます
from rest_framework import permissions
class UserPermission(permissions.BasePermission):
def has_permission(self, request, view) -> bool:
if request.method.lower() == 'post':
return True
return request.user.is_authenticated
def has_object_permission(self, request, view, obj) -> bool:
return obj == request.user
以上になります