운영 원리 : Authentication & Permission
제 3자를 비롯한 모든 사용자에게 동일한 권한을 주는 경우는 극히 드물다.
Authentication
서비스를 이용하는 데에 있어 내가 어느 정도의 권한이 있음을 알려주는(요청하는) 과정
BasicAuthentication
HTTP 자체 기본인증에 기반한 인증방식
HTTP 제어 헤더로 넘긴 ID, PW를 base64 encoding
TokenAuthentication
BasicAuthentication은 보안에 취약하다는 단점
SessionAuthentication은 외부 서비스에서 사용할 수 없다는 단점을 가진 한계로
많은 서비스에서 사용된다.
Mobile Client에 적합
수행과정
1. username과 password를 받아 1:1로 매칭되는 고유 Key 생성 및 발급 (User instance의 생성에 따라 자동으로 생성되는 것은 아님)
2. 발급받은 Token을 API 요청에 담아 인증처리
1. settings.py
INSTALLED_APPS = [
'rest_framework.authtoken',
]
2. views.py
from .models import UserPost
from .serializer import UserPostSerializer
from rest_framework import viewsets
from rest_framework.authentication import TokenAuthentication
class UserPostViewSet(viewsets.ModelViewSet):
authentication_classes = [TokenAuthentication]
queryset = UserPost.objects.all()
serializer_class = UserPostSerializer
3. $ python manage.py migrate
authtoken/models.py의 OneToOneField를 이용해 Token을 발급할 것이기 때문이다.
4.
(1) rest_fraemwork/authtoken/views.py의 ObtainAuthToken을 이용한 생성
(2) Python 명령어를 통한 생성
$ python manage.py drf_create_token <username>
$ python manage.py drf_create_token -r <username> : token을 강제로 재발급
+ 자동으로 token이 생성되기를 원한다면 signal을 이용한 Token 획득
*post_save : DB에 뭔가가 저장된 직후에 특정 동작 수행
5. 생성한 Token을 획득하기 위해 token을 획득할 수 있는 url path 지정한다.
6. url에 대해 POST 요청을 보냄으로써 획득
POST 요청 보낼 때 "Authorization: Token <token>"를 함께 보낸다.
http POST http://127.0.0.8000/userpost/ "Authorization: Token <token>" title="" body=""
7.
인증 성공시 :
request.user = Django User Instance
request.auth = rest_framework.authtoken.models.BasicToken
SessionAuthentication
로그인 될 때마다 저장되는 Session 정보를 참조하여 인증
RemoteUserAuthentication
User 정보가 다른 서비스에서 관리될 때 쓰이는 인증방식 == 원격지에서의 인증방식
전역으로 설정하는 방법
settings.py
DEBUG = False
ALLOWED_HOSTS = ['*']
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
]
}
지역으로 설정하는 방법
views.py
from .models import UserPost
from .serializer import UserPostSerializer
from rest_framework import viewsets
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
class UserPostViewSet(viewsets.ModelViewSet):
authentication_classes = [SessionAuthentication, BasicAuthentication]
queryset = UserPost.objects.all()
serializer_class = UserPostSerializer
serializer.py
from .models import UserPost
from rest_framework import serializers
class UserPostSerializer(serializers.ModelSerializer):
author_name = serializers.ReadOnlyField(source='author.username')
class Meta:
model = UserPost
fields = ['pk', 'author_name', 'title', 'body']
HTTPie에서 인증 요청 보내는 방법
http --auth username:password --form POST http://127.0.0.1:8000/userpost/ title="" body=""
→ 예를 들어, http --auth sss20-02:1234 --form POST http://127.0.0.1:8000/userpost/ title="" body=""
Permission
(인증 요청을 보낸 사용자에 대해서) 서비스를 어느 정도로 이용할 수 있는지에 대한 권한
View 호출 시 가장 먼저 체킹
인증 정보를 기반으로 권한 체크(request.user, request.auth 를 기반으로 권한 체크)
AllowAny
디폴트로 설정된 클래스로, 인증된 요청이든 비인증 요청이든 전부 허용하겠다.
IsAuthenticated
인증된 요청에 대해서만 View호출을 허용하겠다(등록된 사용자에게만 Access 허용)
IsAdminUser
StaffUser에 대해서만 요청을 허용하겠다
(User.is_staff == True 일 대만 허용)
IsAuthenticatedOrReadOnly
비인증 요청에 대해서는 읽기만 허용하겠다
(비인증 요청은 '안전한 http method'만 허용하겠다)
전역으로 설정하는 방법
settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
]
}
지역으로 설정하는 방법
views.py
from .models import UserPost
from .serializer import UserPostSerializer
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated
class UserPostViewSet(viewsets.ModelViewSet):
permission_classes = [IsAuthenticated]
queryset = UserPost.objects.all()
serializer_class = UserPostSerializer
+ FBV decorator를 이용한 설정
from rest_framework.permissions import IsAuthenticated
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def example_view(request, format=None):
Tip. 로그인/로그아웃 버튼 생성
urls.py 에 추가
from django.urls import path, include
from rest_framework import urls
urlpatterns = [
path('api-auth/', include('rest_framework.urls')),
]
이때, authentication_classes = [TokenAuthentication] 이 있어야 한다.
'Server > django' 카테고리의 다른 글
[Django] Filtering & Search (0) | 2020.05.25 |
---|---|
[Django] Pagination (0) | 2020.05.25 |
[Django] View of DRF ( Django Rest Framework ) (0) | 2020.05.04 |
[Django] JSON 직렬화 - Serializer (0) | 2020.04.28 |
[Django] REST Architecture (0) | 2020.04.28 |