[DRF] <Level Three> Django REST Framework - 2. Authentication (Basic, Token, Session, 그리고 JWT)

Alex of the year 2020 & 2021·2020년 9월 3일
5

Django Rest Framework

목록 보기
12/15
post-thumbnail

Authentication

프론트로부터 들어온 요청에 대해 일련의 인증 절차를 수행하여 해당 요청을 보낸 유저에 대한 중요한 정보를 습득하는 과정. 이후에는 permission을 통해 들어온 요청을 수행할지 말지를 결정. (이 유저가 admin이냐 basic이냐 등등을 따져서)

authentication과 permission의 차이를 아는 것이 중요한데,
authentication은 view의 가장 첫 단에서 실행된다. 따라서 당연히 authorization check를 포함한 모든 코드보다 우선한다. 또한 authentication은 들어온 요청의 암호화된 정보들을 스스로 검증할 수 있다. DRF에서 제공하는 authentication는 일반적인 것과는 조금 다른 형식이다.

이 강의에서는 DRF의 독특한 인증 방식, 그리고 이 방식의 장단점, use cases 등을 살펴보고 또한 DRF와 매우 궁합이 좋은 third party package인 JWT에 대해서도 다뤄본다.

Basic Authentication in DRF

  • The most primitive & the least secure way of authentication system
  • Request/Response cycle:
    1. Client는 Server에게 HTTP request를 보낸다.
    2. Server는 401 Unauthorized response를 보내는데, 이 때 올바른 인증 방법을 설명하는 WWW-Authenticate를 header로 담아 보낸다. (ex. WWW-Authenticate: Basic)
    3. Client는 auth credentials(암호화된 인증에 필요한 개인정보)를 Base 64 형태로 인코딩하여 Authorization header에 담아 보낸다. 이 때 Authentication credentials는 암호화된 상태가 아니다. (이 때문에 이 방식을 가장 원시적이고도 안전치 못한 authentication 이라고 일컫는 것이다)
    4. Server는 해당 credentials를 검증한 후 200 혹은 403 status 코드를 보내어 해당 요청을 인가하거나 거절한다.
  • 효율성이 낮고 안전치 않은 방법이기 때문에 이는 testing에서만 주로 사용된다.
  • DRF 공식문서는 만약 BasicAuthentication을 사용한다면 API가 오직 https 환경에서 작동할 때만 사용할 것과 client가 결코 로그인 정보를 영속적으로 저장하지 않는다는 것을 확실히해둔 후 사용할 것을 권고한다.

Token Authentication in DRF

  • The ideal system for authenticating smartphone and desktop clients.
  • Request/Response cycle:
    1. Client는 authentication credential을 딱 한 번만 보낸다.2
    2. Server는 해당 credential을 체크한 후 유효하다면 exclusive signed token을 발행한다. Client는 문자열로 이루어진 이 토큰을 response로 받게 된다.
    3. Client는 앞으로 발생되는 모든 request에 발급받은 token을 Authorization Header에 넣어 보내게 된다.
    4. Server는 들어온 요청 속 token의 유효성을 검증한 후, 유효하다면 해당 요청을 수행한다.
  • Requests module 임포트가 필요
  • React나 Vue와 같은 framework를 사용하여 제작된 SPA(Single Page Applications)에서도 주로 사용되는 방식
  • 이러한 Authentication Token은 cookie 혹은 browser의 localStorage에 저장된다. 그러나, localStorage 저장은 XSS 공격에 취약하기 때문에 상당히 위험한 일이다. 따라서 httpOnly cookie를 사용하는 것이 더욱 안전한 방법으로 여겨진다. 왜냐하면 이 방법을 사용할 경우 JavaScript을 통한 토큰 접근이 허용되지 않기 때문이다. 단, localStorage를 이용할 때만큼의 유연성은 보장받지 못하게 된다.

개발을 하다보면 각 프로젝트의 요구사항이 다 다른만큼 SPA적 관점에서 '통상적으로 사용되는' Authentication scheme을 찾기는 어려울 것이다. 그러나 언제나 안전하고 믿을만한 솔루션을 사용해야 한다는 것은 공통적인 일이다. DRF 공식문서는 이러한 관점에서 Session Authentication 방식을 추천한다. (Session Authentication은 Final Project에서 사용할 예정.)

Session Authentication in DRF

  • Django의 default session backend를 authentication을 위해 사용한다.
  • The safest and most appropriate way for authenticating AJAX clients that are running in the same session context as your website, and uses a combination of Sessions and Cookies.
  • Request/Response cycle:
    1. Users는 일반적으로 Login Form(보통 ID, PW)을 이용하여 authentication credentials를 Server로 보낸다.
    2. Server는 받은 data를 체크하여 해당 data가 맞다면 이에 상응하는 Session object를 만들어 DB에 저장한 후 Session ID를 다시 Client에게 보낸다.
    3. User가 받은 Session ID는 Browser의 Cookie로 저장되고 향후 보내질 모든 request에 들어가게 된다. 그리고 Server는 그 Cookie를 검사하게 된다.
    4. Client가 로그아웃할 때에 Session ID는 client와 Server 사이드 모두에서 삭제된다. (다시 로그인을 할 때에는 새로운 Session ID가 발급되므로 상관 없다.)
    5. 이 Session Authentication 과정이 잘 이루어지면 장고는 그에 맞는 User Object를 request.user를 통해 보내온다. 하지만, 이 과정이 이루어지지 않았을 경우(for non-authenticated requests,) AnonymousUser instance를 대신 보내게 된다.

정말 중요한 것은,
일단 한 번 Session Authentication이 잘 이루어진 이후에 DRF는 UNSAFE한 HTTP method에 대해(PUT, PATCH, POST, DELETE) 유효한 CSRF(Cross-Site Request Forgery, 사이트 간 요청 위조) 토큰을 전달받고자 한다는 것이다. (CSRF 토큰은 CSRF 공격에 대비할 수 있는 보안책)

JWT in DRF

  • Json Web Token
  • token-based authentication의 new standard. 여타 token-based authentication과 다른 점은 구조상 DB 유효성 검사를 필요로 하지 않는다는 점이다.
  • JWT는 pip로 설치 가능한django-rest-framework-simplejwt package사용하여 DRF에서 손쉽게 사용이 가능하다.


references:
https://effectivesquid.tistory.com/entry/Base64-%EC%9D%B8%EC%BD%94%EB%94%A9%EC%9D%B4%EB%9E%80 (Base64)

profile
Backend 개발 학습 아카이빙 블로그입니다. (현재는 작성하지 않습니다.)

0개의 댓글