AI 웹 개발 과정/DRF 특강

DRF JWT 사용하기

만 기 2022. 7. 27. 00:19

 

JWT(Json Web Token) 

사용자 인증을 위해 사용하는 암호화된 토큰인증 방식

 

 

토큰 인증 방식 

사용자가 인증을 수행하면 서버에서는 사용자의 정보를 저장하지 않고 토큰값으로 브라우저에게 응답한다.

브라우저는 받은 토큰값으로 사용자만 사용할 수 있는 서비스를 요청할때 헤더에 함께 보내준다.

 

 

세션(Session) 방식과 비교하며 JWT 필요성 알기

세션 방식은 서버의 메모리, 데이터 베이스와 같은 서버의 자원들을 사용해서 사용자의 정보를 유지시키는 방식이다.

토큰방식 보다 보안에 강하다는 점이 있지만, 서버의 확장성이 떨어지고 서버의 자원(세션을 저장, 유지할 공간)이 많이 필요하게된다. 하지만 토큰 방식을 사용하면 서버에서 발행해주는 토큰을 가지고 브라우저의 저장소에 토큰을 유지시키고, 서버는 요청이 들어왔을때 해당 토큰이 유효한지만 체크하면 되게 된다.

 

 

JWT 의 단점

- 많은 필드가 추가되면 토큰이 커질 수 있는데, 토큰은 거의 모든 요청에 대해 전송 되므로 데이터 트래픽 크기에 영향을 미쳐 네트워크 부하가 심해질 수 있다.

- 토큰이 클라이언트에 저장되어 DB에서 사용자 정보를 수정하더라도 토큰에 직접 적용 할 수 없다.

 

 

JWT 구조

HEADER . PAYLOAD . VERIFY_SIGNATURE

ex) eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

 

1. HEADER

  • JWT를 검증하는데 필요한 정보를 가진다.
  • 암호화 알고리즘과 토큰 타입, Key id 등 정보
  • ex)
    {
      "typ": "JWT",    # 토큰 타입
      "alg": "HS256"   # 알고리즘
    }

2. PAYLOAD

  • 실질적으로 인증에 필요한 데이터를 저장
  • {
      "token_type": "access",   # 토큰의 종류. 여기서는 access 토큰입니다.
      "exp": 1656293275,   # 토큰의 만료시간입니다. (Numeric Date)
      "iat": 1656293095,   # 토큰의 발행시간입니다. (Numeric Date)
      "jti": "2b45ec59cb1e4da591f9f647cbb9f6a3",   # json token id 입니다.
      "user_id": 1   # 실제 사용자의 id값이 들어있습니다.
    }
  • 토큰 만료시간 지나면 새로 발급 받아야한다.

3. VERIFY SIGNATURE

  • 토큰 자체의 진위여부를 판단하는 용도로 사용
  • Base64UrlEncoding 된  header 와 payload 의 정보를 합친 뒤 SECRET_KEY 를 이용하여 Hash 를 생성하여 암호화 한다.
  • HMACSHA256(
      base64UrlEncode(header) + "." +
      base64UrlEncode(payload),
      SECRET_KEY
    )

 

 

DRF에서 JWT 사용하기

 

1. simple jwt 설치

pip install djangorestframework-simplejwt

 

2. settings.py 수정

INSTALLED_APPS = [
    ...
    'rest_framework_simplejwt',
    ...
]
REST_FRAMEWORK = {
  ...
    'DEFAULT_AUTHENTICATION_CLASSES': [ # session 혹은 token을 인증 할 클래스 설정
        ...
        # JWT 인증 방식 추가하기
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ],
...
}

 

3. urls.py

user/urls.py

from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)

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

 

* view 는 따로 작성하지 않아도 됨.

 

 

Postman 에서 JWT 테스트

1. 사용자 정보 서버에 보내고 토큰 받기

urls.py 에 추가한 url 주소로 TokenObtainPairView 를 실행하고 토큰을 받음.

 

2. 인증된 사용자 정보 조회하기

user/views.py 

class UserView(APIView): 
    authentication_classes = [JWTAuthentication]

    def get(self, request):
        user = request.user
        return Response(UserSerializer(user).data)

헤더에 KEY = Authorization, VALUE = Bearer (공백 한칸) 발급받은 access 토큰  형식을 맞춰서 실어 보낸다.

 

3. 만료된 access 토큰을 refresh 토큰으로 재요청해서 access 토큰 재발급 받기

refresh url 주소 사용

 

 

JWT 옵션 설정하기

settings. 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),
}

 

 

 

다음편

커스텀 JWT , 프론트엔드에서 JWT 환경 구성

'AI 웹 개발 과정 > DRF 특강' 카테고리의 다른 글

DRF 커스텀 JWT 클레임 , 프론트엔드에서 JWT 환경 구성  (0) 2022.08.11
django-dotenv  (0) 2022.07.30
DRF 테스트 코드 작성하기 1  (0) 2022.07.11
DRF 를 이용한 JWT 사용하기  (0) 2022.06.27
DRF 퀴즈2  (0) 2022.06.24