REST 프레임워크를 이용하여 로그인을 구현하는 방식에는 2가지가 있다. 바로 토큰과 세션 기반인데, 프로젝트에서는 토큰 기반 인증을 사용하여 다음과 같은 로직에 따라 구현하였다.


장고의 REST 로그인 - Token 인증

  • 사용자에게서 User Credential 정보를 받아 authenticate를 진행한다. User Credential은 로그인할 때 입력받을 정보로, 보통 usernamepassword를 생각하면 된다. 프로젝트 내 username은 이메일 형식으로 받았다.
  • 해당 유저를 특정할 수 있는 Hash 값을 데이터베이스에 저장한다.
  • 세션에 저장된 Hash 값을 특정할 수 있는 token를 생성한다.
  • 생성된 token을 로그인 요청이 왔을 때 response로 돌려준다.
  • 이후 요청에서, 전달해준 token값이 requestHeader에 담겨올 경우 해당 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.viewsObtainAuthToken 클래스이다. 또, 해당 뷰에서 사용자 인증에 필요한 시리얼라이저도 제공하고 있어 그대로 사용할 수 있다.

해당 클래스는 APIView를 상속받아 post 메서드를 정의하고 있다. 이 post 메서드는 위의 로그인 로직대로 인증을 거친 후 토큰을 반환해준다. 프로젝트에서는 해당 메서드를 참고하여 따로 post 메서드를 정의하고 사용하고 있다.


로그아웃 API

토큰 기반 인증에서는 해당 토큰을 클라이언트 측에 넘겨주고 이후 요청이 올 때 넘겨받는 토큰값이 일치하면 로그인한 상태로 간주한다. 즉, 상태를 계속해서 체크하지 않고 요청이 올 때만 인증을 확인하는 stateless 방식의 인증이라 할 수 있다.

그렇다면 로그아웃을 하는 경우에는 해당 토큰값이 더이상 유효하지 않도록 처리해주어야 한다. 그 방식에는 2가지가 있는데, 바로 넘겨준 토큰값을 지우는 것과 토큰 자체에 유효기간을 설정하는 방법이다.

첫번째 방식으로는 로그아웃 요청이 왔을 때 데이터베이스에 저장되어 있는 토큰 값을 삭제하면 된다. 두번째 방식은 유효기간을 정한 뒤 그 시간을 넘길 경우 데이터베이스에서 토큰을 지우는 방식이다.



마치며

로그인 및 로그아웃 API에 대한 소스코드는 깃헙을 참고하기 바란다.


Julia Hwang

디발자를 꿈꾸는 웹개발자의 블로그입니다.