DRF에서 지원하는 인증
rest_framework.authentication.SessionAuthentication
- 웹 프론트엔드와 장고가 같은 호스트를 쓴다면 세션 인증을 사용할 수 있다
- 하지만 외부 서비스/앱 ( ex. react, 안드로이드 앱)에서는 사용할 수 없다
rest_framework.authentication.BasicAuthentication
- 매 요청 시마다 인증을 수행한다
- 매번 username/password를 넘기는 것이 보안상 위험하다
rest_framework.authentication.TokenAuthentication
- 매 요청 시마다 인증을 수행한다
- 초기에 username/password로 Token을 발급받고, 이 Token을 매 API 요청에 담아 보내 인증 처리
Token 모델
rest_framework에 authtoken 앱 속에 있음
- User모델과 일대일 관계
- 각 User별 Token은 수동으로 생성해줘야 한다
- Token은 유저별로 유일하며, Token 만으로 인증을 수행한다 ← TokenAuthentication 통해
Token 생성
방법1. authtoken앱의 ObtainAuthToken 뷰를 통한 획득 및 생성
# restframework/authtoken/views.py
class ObtainAuthToken(APIView):
def post(self, request, *args, **kwargs):
...
token, created = Token.objects.get_or_create(user=user)
return Response({'token':token.key})
방법2. Signal을 통한 자동 생성
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
방법 3. 커스텀 Management 명령을 통한 생성
# Token이 없을 때 생성하나 생성된 Token을 변경하지 않는다
python manage.py drf_create_token <username>
# 강제로 Token 재생성하기
python manage.py drf_create_token -r <username>
Token 획득
1. 먼저 obtain_auth_token을 노출하기
# settings.py
INSTALLED_APPS = [
...
'rest_framework.authtoken'
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES" : [
'rest_framework.authentication.ToeknAuthentication',
...
]
...
}
# urls.py
from rest_framework.authtoken.views import obtain_auth_token
urlpatterns += [
path('api-token-auth/', obtain_auth_token)
]
2. HTTPie를 통한 Token 획득
쉘 > http POST http://주소/api-token-auth/ username="유저명" password="암호"
→ "token": "9cdd704lfjkd30eignd9oeoghn664048djeiojgio23" 같은 형태로 토큰 할당됨
3. HTTPie를 통한 Token 활용 예
- http GET http://localhost:8000/api/post "Authorization: Token 9cdd704lfjkd30eignd9oeoghn664048djeiojgio23"
- http POST http://localhost:8000/api/post "Authorization: Token 9cdd704lfjkd30eignd9oeoghn664048djeiojgio23" message="hello"
- http PATCH http://localhost:8000/api/post/16/ "Authorization: Token 9cdd704lfjkd30eignd9oeoghn664048djeiojgio23" message="patched"