
DRF를 사용한 프로젝트를 진행하며JWT를 사용하여 인증/인가 방식을 구현하였습니다. 이번 포스트를 작성하며 DRF의 simpleJWT와 dj-rest-auth 패키지에서 제공하는 기능의 코드를 보며 로그인시, 토큰을 발급하게 되는 과정을 간단하게 정리해보고, 사용되는 settings 값이 무엇인지 확인하여 추후 구현할 서비스의 요구에 맞추어 변경해보고자 합니다.
로그인시 관여되는 요소들을 큰 단위로 나누어 정리하였습니다.
사용자로부터 입력받은 로그인 정보를 바탕으로 검증을 한 후, 토큰을 발급받아 응답으로 반환하는 View클래스 입니다. 사용되는 메소드로는 크게 post, login, get_response가 있습니다.
request를 받아 요청을 처리하게되는 메소드입니다. LoginView 클래스에 정의된 serializer_class인 LoginSerializer를 사용하여 멤버 변수인 serializer를 할당하고, 로그인된 정보를 serializer를 통해 검증한 후, login(), get_response() 메소드를 순차적으로 호출하게 됩니다.
def post(self, request, *args, **kwargs):
self.request = request
self.serializer = self.get_serializer(data=self.request.data)
self.serializer.is_valid(raise_exception=True)
self.login()
return self.get_response()
login() 메소드는 토큰을 발급받기 위해 사용할 토큰 모델을 설정하고 발급받는 메소드입니다. 또한 사용자의 설정에 따라 로그인 요청을 한 사용자를 세션 로그인을 처리합니다.
settings : REST_USE_JWT, REST_SESSION_LOGIN
LoginView의 멤버 변수인 serializer를 사용하여 멤버 변수인 user를 초기화REST_USE_JWT가True로 설정되어 있으면 utils.jwt_encode() 메소드를 사용하여 멤버 변수인 access_token과 refresh_token을 초기화합니다.False이거나 설정되어 있지 않다면, REST_AUTH_TOKEN_MODEL로 설정된 토큰 모델 혹은 rest_framework.authtoken.models.Token 모델의 토큰으로 token을 초기화합니다.REST_SESSION_LOGIN이 False로 설정되어 있지 않으면 process_login()메호드를 호출하여 사용자를 로그인시킵니다.get_response() 메소드는 설정에 따라 사용자에게 반환할 응답을 구성하여 반환하는 메소드입니다. JWT_AUTH_RETURN_EXPIRATION 설정으로 토큰의 만료 시기를 응답에 포함시킬지 여부를 판단하고, JWT_AUTH_HTTPONLY 설정에 따라 멤벼 변수인 refresh를 초기화합니다.
settings : REST_USE_JWT, JWT_AUTH_RETURN_EXPIRATION, JWT_AUTH_HTTPONLY
REST_USER_JWT가 설정되어있지 않거나 False인 경우, 멤버 변수 token으로 응답을 생성합니다.REST_USE_JWT가 True일 경우,JWT_AUTH_RETURN_EXPIRATION가 True로 설정되어있으면 응답에 access token, refresh token의 만료 시간을 추가합니다.JWT_AUTH_HTTPONLY가 True로 설정되어 있으면 refresh token을 blank 처리합니다.Response 객체로 wrap하여 반환합니다.사용자로부터 입력받은 로그인 정보를 사용하여 인증 후, 설정된 방법으로 사용자 정보를 가져와 반환하는 serializer 클래스입니다. LoginView의 post() 메소드 내부에서 is_valid()를 통해 validate() 메소드가 호출됩니다.
필드별로 검증을 마친 후, 해당하는 사용자를 찾아 사용자가 활성화된 사용자인지 확인하여 serializer의 데이터에 user 키로 추가합니다. 만약 해당하는 사용자가 없는 경우, ValidationError를 발생시킵니다.
페이로드로 주어진 사용자 정보를 바탕으로 일치하는 사용자가 있는 경우, 설정에 따라 allauth 방식 혹은 ORM을 사용하여 사용자를 찾아 반환합니다.
allauth가 settings.INSTALLED_APPS에 있는 경우, allauth를 사용하여 사용자를 찾아 반환합니다.ORM을 사용하여 사용자를 반환합니다.serializer 데이터에 사용자를 추가하기 전, 해당 사용자가 활성화된 사용자인지 확인하는 메소드입니다. 만약 사용자가 활성화되지 않은 사용자의 경우, ValidationError를 발생시킵니다.
settings : REST_AUTH_SERIALIZERS.JWT_TOKEN_CLAIMS_SERIALIZER
jwt_encode(user)
입력받은 유저의 token을 반환하는 메소드입니다. REST_AUTH_SERIALIZERS의 JWT_TOKEN_CLAIMS_SERIALIZER로 설정된 serializer가 없으면 rest_framework_simplejwt의 TokenObtainPairSerializer를 사용하여 get_token(user) 메소드를 호출하여 토큰을 반환합니다.
TokenObtainPairSerializer의 token_class는 RefreshToken 입니다. 클래스 메소드인 get_token(user) 메소드를 호출하게되면, 설정된 token_class의 for_user(user) 메소드를 호출하여 토큰을 발급하게 됩니다.
for_user(user) 메소드는 인자로 받은 유저의 ID를 토큰 클레임에 추가하여 토큰을 반환하는 메소드입니다.