Django 인증 API [2편] - REST의 토큰기반 인증
장고의 REST 로그인 - Token 인증
- 사용자에게서 User Credential 정보를 받아
authenticate
를 진행한다. User Credential은 로그인할 때 입력받을 정보로, 보통username
과password
를 생각하면 된다. 프로젝트 내username
은 이메일 형식으로 받았다. - 해당 유저를 특정할 수 있는 Hash 값을 데이터베이스에 저장한다.
- 세션에 저장된 Hash 값을 특정할 수 있는
token
를 생성한다. - 생성된
token
을 로그인 요청이 왔을 때response
로 돌려준다. - 이후 요청에서, 전달해준
token
값이request
의Header
에 담겨올 경우 해당request
는 전달받은token
값에 해당하는 사용자를 인증된(=로그인된) 상태로 간주한다.
[Header] Authorization: Token "토큰값(문자열)"
필요한 것들
설정
base.py
에 레스트 프레임워크에서 제공하는 토큰 기반 인증을 사용하겠다는 설정을 넣어주고 migrate
를 통해 Token
테이블을 생성해준다. 테이블을 생성하기 위해서는 반드시 INSTALLED_APPS
에 토큰 앱을 표기하여야 한다.
# config/base.py
# REST_API 설정
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication'
)
}
INSTALLED_APPS = [
'rest_framework.authtoken',
...
]
이 때 BasicAuthentication
은 보안이 취약하므로 사용하지 않는다.
토큰 생성하기
토큰 테이블이 생성되었다면 인터프리터를 실행하여 토큰을 만들어보자.
from rest_framework.authtoken.models import Token
user = MyUser.objects.get(id=1)
token = Token.objects.create(user=user)
print(token)
# 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
이미 유저가 생성되어 있는 경우에는 get_or_create()
메서드를 사용하여 토큰이 없을 경우 해당 사용자에 대한 토큰을 생성해주고 있는 경우 그대로 가져오는 방식으로 메서드를 정의한다.
for user in MyUser.objects.all():
Token.objects.get_or_create(user=user)
같은 방식으로 유저 모델 아래에 토큰을 생성하는 메서드를 정의해준다.
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token
@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)
해당 메서드는 REST 프레임워크 문서에 자세하게 기술되어 있다. (문서 보러가기)
로그인 API
토큰기반 인증을 사용할 경우 이미 토큰을 보내는 API 또한 불러와 바로 사용할 수 있게 되어 있다. 바로 rest_framework.authtoken.views
내 ObtainAuthToken
클래스이다. 또, 해당 뷰에서 사용자 인증에 필요한 시리얼라이저도 제공하고 있어 그대로 사용할 수 있다.
해당 클래스는 APIView
를 상속받아 post
메서드를 정의하고 있다. 이 post
메서드는 위의 로그인 로직대로 인증을 거친 후 토큰을 반환해준다. 프로젝트에서는 해당 메서드를 참고하여 따로 post
메서드를 정의하고 사용하고 있다.
로그아웃 API
토큰 기반 인증에서는 해당 토큰을 클라이언트 측에 넘겨주고 이후 요청이 올 때 넘겨받는 토큰값이 일치하면 로그인한 상태로 간주한다. 즉, 상태를 계속해서 체크하지 않고 요청이 올 때만 인증을 확인하는 stateless 방식의 인증이라 할 수 있다.
그렇다면 로그아웃을 하는 경우에는 해당 토큰값이 더이상 유효하지 않도록 처리해주어야 한다. 그 방식에는 2가지가 있는데, 바로 넘겨준 토큰값을 지우는 것과 토큰 자체에 유효기간을 설정하는 방법이다.
첫번째 방식으로는 로그아웃 요청이 왔을 때 데이터베이스에 저장되어 있는 토큰 값을 삭제하면 된다. 두번째 방식은 유효기간을 정한 뒤 그 시간을 넘길 경우 데이터베이스에서 토큰을 지우는 방식이다.