[Vue] CORS와 Django의 Authentication

작성:    

업데이트:

카테고리:

태그: ,

Server & Client

Server

  • 클라이언트에게 ‘정보’, ‘서비스’를 제공하는 컴퓨터 시스템
  • 정보 & 서비스
    • Django를 통해 응답한 template
    • DRF를 통해 응답한 JSON


Client

  • 서버에게 그 서버가 맡는(서버가 제공하는) 서비스를 요청
  • 서비스 요청을 위해 필요한 인자를 서버가 요구하는 방식에 맞게 제공
  • 서버로부터 반환되는 응답을 사용자에게 적절한 방식으로 표현하는 기능을 가진 시스템


정리

Server : 정보 제공

  • DB와 통신하며 데이터를 CRUD
  • 요청을 보낸 Client에게 이러한 정보를 응답


Client : 정보 요청 & 표현

  • Server에게 정보(데이터) 요청
  • 응답 받은 정보를 잘 가공하여 화면에 보여줌


CORS

SOP

  • 동일 출처 정책(Same Origin Policy)
  • 특정 출처(origin)에서 불러온 문서나 스크립트가 다른 출처에서 가져온 리소스와 상호작용 하는 것을 제한하는 보안 방식
  • 잠재적으로 해로울 수 있는 문서를 분리함으로써 공격받을 수 있는 경로를 줄임


Origin(출처)

  • 두 URL의 Protocol, Post, Host가 모두 같아야 동일한 출처
  • 경로가 달라도 위의 3가지가 같으면 동일한 출처
  • (http, https), (domain), (:8000, :8001) 등은 다르면 다른 출처


CORS

  • Cross-Origin Resource Sharing
  • 교차 출처 리소스(자원) 공유
  • 추가 HTTP header를 사용하여, 특정 출처에서 실행중인 웹 애플리케이션이 다른 출처의 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제
  • 리소스가 자신의 출처(Domain, Protocol, Port)와 다를 때 교차 출처 HTTP 요청을 실행
  • 보안상의 이유로 브라우저는 교차 출처 HTTP 요청을 제한(SOP)
  • 예를 들어 XMLHttpRequest는 SOP를 따름
  • 다른 출처의 리소스를 불러오려면 그 출처에서 올바른 CORS header를 포함한 응답을 반환해야 함


CORS Policy

  • 교차 출처 리소스 공유 정책
  • 다른 출처(origin)에서 온 리소스를 공유하는 것에 대한 정책
  • SOP과 대조


django-cors-headers 라이브러리

pip install django-cors-headers
# settings.py

INSTALLED_APPS = [
  ...
  'corsheaders',
  ...
]

MIDDLEWARE = [
  ...
  # CommonMiddleware보다 위에 위치
  'corsheaders.middleware.CorsMiddleware',
  ...
  'django.middleware.common.CommonMiddleware',
  ...
]

CORS_ALLOWED_ORIGINS = [
  # Vue LocalHost
  'http://localhost:8080',
]
  • INSTALLED_APPS에 추가
  • MIDDLEWARE 추가 : 순서는 CommonMiddleware보다 상단에!
  • CORS_ALLOWED_ORIGINS에 교차 출처 자원 공유를 허용할 Domain 등록


Authentication & Authorization

Authentication

  • 인증, 입증
  • 자신이라고 주장하는 사용자가 누구인지 확인하는 행위
  • 모든 보안 프로세스의 첫 번째 단계(가장 기본 요소)
  • 최소한의 인증이 되어있는지를 확인
  • 401 Unauthorized : 비록 HTTP 표준에서는 미승인(unauthorized)이지만, 의미상 비인증(unauthenticated)을 의미


Authorization

  • 권한 부여, 허가
  • 사용자에게 특정 리소스 또는 기능에 대한 액세스 권한을 부여하는 과정(절차)
  • 보안 환경에서 권한 부여는 항상 인증을 따라야 함
    • 예를 들어, 사용자는 조직에 대한 액세스 권한을 부여받기 전에 먼저 자신의 ID가 진짜인지 먼저 확인해야 함
  • 서류의 등급, 웹페이지에서 글을 조회 & 삭제 & 수정할 수 있는 방법, 제한 구역
    • 인증이 되었어도 모든 권한을 부여 받는 것은 아님
  • 403 Forbidden
    • 401과 다른 점은 서버는 클라이언트가 누구인지 알고 있음


DRF Authentication

다양한 인증 방식

  1. Session Based
  2. Token Based
    • Basic Token
    • JWT
  3. Oauth
    • google
    • facebook


JWT

JWT란?

  • JSON Web Token
  • JSON 포맷을 활용하여 요소 간 안전하게 정보를 교환하기 위한 표준 포맷
  • 암호화 알고리즘에 의한 디지털 서명이 되어 있기 때문에 JWT 자체로 검증 가능
  • JWT 자체가 필요한 정보를 모두 갖기 때문에(self-contained) 이를 검증하기 위한 다른 검증 수단(ex. table)이 필요 없음
  • 사용처 : Authentication, Information Exchange


특징

  • 기본 토큰 인증 체계와 달리 JWT 인증 확인은 DB를 사용하여 토근의 유효성을 검사할 필요가 없음
  • 즉, JWT는 DB에서 유효성 검사가 필요 없음
  • JWT 자체가 인증에 필요한 정보를 모두 갖기 때문(self-contained)
  • 이는 세션 혹은 기본 토큰을 기반으로 한 인증과의 핵심 차이점

  • 토큰 탈취시 서버 측에서 토큰 무효화가 불가능(블랙리스팅 테이블 활용해 해결)
  • 매우 짧은 유효기간(5min)과 Refresh 토큰을 활용하여 구현
  • MSA(Micro Server Architecture) 구조에서 서버간 인증에 활용
  • One Source(JWT) Multi Use 가능


사용 방법

$ pip install django-allauth
$ pip install dj-rest-auth
# settings.py
INSTALLED_APPS = [
  ...
  # token authentication
  'rest_framework.authtoken',

  # DRF auth 담당
  'dj_rest_auth',
  'dj_rest_auth.registration',

  # django allauth
  'allauth',
  'allauth.account',

  # allauth 사용을 위해 필요
  'django.contrib.sites',
]
# settings.py
# django.contrib.sites에서 등록 필요
SITE_ID = 1

# drf 설정
REST_FRAMEWORK = {
  # 기본 인증방식 설정
  'DEFAULT_AUTHENTICATION_CLASSES': [
    'rest_framework.authentication.TokenAuthentication',
  ],

  # 기본 권한 설정
  'DEFAULT_PERMISSION_CLASSES': [
    # rest_framework.permissions.AllowAny',           # 기본적으로 모두에게 허용
    'rest_framework.permissions.IsAuthenticated',     # 기본적으로 인증받아야 사용
  ],
}
# urls.py
urlpatterns = [
  path('admin/', admin.site.urls),
  ...
  # 패턴은 자유롭게 설정 가능. 포워딩만 dj_rest_auth 로
  path('api/v1/accounts/', include('dj_rest_auth.urls')),
  path('api/v1/accounts/signup/', include('dj_rest_auth.registration.urls')),
]

댓글남기기