DRF - JWT 적용시키기

Dongwoo Kim·2022년 8월 5일
0

DRF

목록 보기
3/9
post-custom-banner

1. JWT 란?

Json Web Token의 약자로 json형태의 token을 사용한 인증 방식

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object.
https://jwt.io/introduction

2. JWT 구조

JWT는 점(.)을 기준으로 3부분으로 구분된다.

  • Header
  • Payload
  • Signature
Header.Payload.Signature

https://jwt.io/introduction

1) Header

JWT를 검증하는데 필요한 정보를 가진 데이터
Base64Url로 인코딩된다.

{
  "alg": "HS256", 	# 알고리즘
  "typ": "JWT"		# 토큰 타입
}

2) Payload

인증에 필요한 데이터와 사용자(entity)에 대한 추가 데이터 기술,
Base64Url로 인코딩된다.

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

3) Signature

Base64Url로 인코딩된 header 와 payload 의 정보를 합친 뒤 SECRET_KEY 를 이용하여 Hash 를 생성하여 암호화한 부분

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

3. 세션 인증과 차이점

1) 세션 로그인, 사용자 인증 방식

  1. Client에서 로그인 정보(ID, PW)를 Server로 전달
  2. Server에서 로그인 정보에 따른 로그인 가능 여부 판단
  3. 로그인이 가능하면 사용자 정보를 Server에서 저장
  4. 이후 사용자 인증이 필요할 때마다 Server에 저장한 정보로 판단

2) JWT 로그인, 사용자 인증 방식

  1. Client에서 로그인 정보(ID, PW)를 Server로 전달
  2. Server에서 로그인 정보에 따른 로그인 가능 여부 판단
  3. 로그인이 가능하면 JWT를 Client에 발급하고 Client가 JWT를 저장
  4. 이후 사용자 인증이 필요할 때마다 Client에 저장한 JWT로 판단

3) 차이점

가장 큰 차이점은 로그인 정보, 사용자 정보를 Server에 저장하는지 Client에 저장하는지 이다.
로그인 정보를 Server에 저장할 경우 로그인한 유저가 많아질 경우 Server에서 감당해아할 데이터가 많아짐으로 과부하가 올 수 있다. 하지만 JWT와 같이 Client에서 저장할 경우 Server에서는 해당 토큰의 유효성 여부만 판단하면 되기 때문에 이를 피할 수 있다.

4. DRF에 JWT 적용시키기

1) simplejwt 패키지 설치

$ pip install djangorestframework-simplejwt

2) setting.py에 인증방식 추가

# setting.py

INSTALLED_APPS = [
    ...
    'rest_framework_simplejwt',
]

...

'DEFAULT_AUTHENTICATION_CLASSES': [
		...
       'rest_framework_simplejwt.authentication.JWTAuthentication',
],

3) urls.py에 url 추가

# user/urls.py
...
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)

urlpatterns = [
    ...
    path('token/', TokenObtainPairView.as_view(), name='token'),
    path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    ...
]

4) Postman으로 테스트

5) JWT 세부옵션 설정

# setting.py
from datetime import timedelta
...

SIMPLE_JWT = {
		# Access 토큰 유효 시간 설정하기
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
		# Refresh 토큰 유효 시간 설정하기
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),

    'ROTATE_REFRESH_TOKENS': False,
    'BLACKLIST_AFTER_ROTATION': False,
    'UPDATE_LAST_LOGIN': False,

    'ALGORITHM': 'HS256',
    'SIGNING_KEY': SECRET_KEY,
    'VERIFYING_KEY': None,
    'AUDIENCE': None,
    'ISSUER': None,
    'JWK_URL': None,
    'LEEWAY': 0,

    'AUTH_HEADER_TYPES': ('Bearer',),
    'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
    'USER_ID_FIELD': 'id',
    'USER_ID_CLAIM': 'user_id',
    'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',

    'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
    'TOKEN_TYPE_CLAIM': 'token_type',
    'TOKEN_USER_CLASS': 'rest_framework_simplejwt.models.TokenUser',

    'JTI_CLAIM': 'jti',

    'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
    'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
    'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}
profile
kimphysicsman
post-custom-banner

0개의 댓글