_won_
wonprogrammer
_won_
전체 방문자
오늘
어제
  • 분류 전체보기
    • woncoding
      • TIL
      • WIL
    • source Code
      • Python
      • Programmers
      • BAEKJOON

블로그 메뉴

  • 방명록

티스토리

Github · Wonprogrammer
hELLO · Designed By 정상우.
_won_

wonprogrammer

woncoding/TIL

TIL | 10.26.수 [Django : DRF]

2022. 10. 27. 12:16

- Django Rest Framework

 

DRF 사용자 기능

  • 쿠키 세션 방식 로그인과 토큰 방식 로그인의 차이를 이해한다.
  • 쿠키와 로컬스토리지의 차이를 이해한다.
  • JWT의 구조를 이해한다.
  • 장고에서 JWT를 이용해서 회원가입과 로그인을 구현할 수 있다.
  • 브라우저의 로컬스토리지에 백엔드에서 받은 토큰을 저장할 수 있다.
  • 프론트에서 로컬스토리지의 토큰을 헤더에 실어서 백엔드로 보낼수 있다.
  • 포스트맨에서 헤더에 토큰을 실어서 백엔드로 보낼 수 있다.
  • 토큰의 만료기간을 설정할 수 있다.
  • 토큰이 만료되면 refresh token을 다시 받아올 수 있다.

 

 

 


 

 

 

 

[Token - login]

  • 퓨어 장고는 세션이 남게 되서 stateless 하지 않다. 따라서 데이터베이스의 과부하 or 세션이 없어지면 사용자의 계정이 날라가는 등의 문제점이 있다.
  • 세션과 다르게 Token은 사용자 자체가 가진 암호화 값으로 서버에 인증을 하면 된다. 따라서, 세션처럼 모든 토큰을 데이터 베이스에 저장을 하지 않아도 되기 때문에 과부하 or 다양한 문제를 해결 할 수 있다.

 


 

 

[쿠키 vs 로컬스토리지]

  • cookies : 매번 모든 요청에 실려서 보내진다. / 만료일이 있다
  • local storage : 쿠키보다 많은 양을 저장할 수 있다. / 만료일이 없다

👉쿠키와 local storage : 상관없이 사용자의 정보를 가지고 있는 Token이 저장될 수 있다. 이 중에 우리는 local storage 사용

 

 

 


 

 

 

[JWT]

JWT = Json Web Token

 

JWT는 토큰 인증 방식의 대표주자 이다. JWT 토큰 구조는 HEADER.PAYLOAD.VERIFY_SIGNATURE 로 이루어져 있으며, 각 데이터는 온점(.)으로 구분된다.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

1) Header : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
2) payload : eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
3) VERIFY_SIGNATURE : SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

 

1) HEADER :

JWT를 검증하는데 필요한 정보를 가진 데이터이다.  VERIFY_SIGNATURE 에 사용한 암호화 알고리즘과 토큰 타입, key 의 id 등의 정보를 가지고 있습니다. 난해한 문자열처럼 보이지만 암호화된 값은 아닙니다. 

# 헤더 값 해석하면

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

 

 

2) PAYLOAD :

실질적으로 인증에 필요한 데이터를 저장한다.

데이터 각각의 필드를 클레임(claim) 이라고 하고, 대부분의 경우 클레임에 username 또는 user_id 를 포함합니다.

인증시에 payload에 있는 username을 가져와서 사용자의 정보를 인증할 때 사용해야 하기 때문니다.

또한 payload에서 중요하게 살펴보아야 할 정보는 **토큰 발행시간(iat)**와 토큰 만료시간(exp) 입니다. 토큰의 만료 시간이 지나면 새로운 토큰을 발급받아야 한다.

# 사용자를 인증하는 정보를 가지고 있어 payload 정보를 기준으로 로그인한다.

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 : 

VERIFY SIGNATURE 는 토큰 자체의 진위여부를 판단하는 용도로 사용한다. 

VERIFY SIGNATURE 는 Base64UrlEncoding 된  header 와 payload 의 정보를 합친 뒤 SECRET_KEY 를 이용하여 Hash 를 생성하여 암호화 합니다.

→  Header, payload가 서류라면 VERIFY_SIGNATURE는 서류에 찍는 도장과 같다. 아무리 서류가 진짜라고 해도 인증된 도장이 없으면 서류가 효력이 없는거 처럼 VERIFY_SIGNATURE도 도장과 같은 역할을 한다.

 

↓

 

 

[DRF에서 JWT사용]

 

 

  • 1) JWT를 settings.py에 맞게 import 해주고, url설정도 해준다.
     
# settings.py

INSTALLED_APPS = [
    'rest_framework_simplejwt',   # 얘까지 추가
]

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    )
}
# urls.py

from django.urls import path, include
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'),
]
  • 1-1) username 과 password 등 views.py에서 아무작업하지 않아도 JWT에서 알아서 만들어 준다.

 

  • 2) createsuperuser 후 postman에서 해당 아이디로 POST 해주면 refresh token값 과 access token 값이 반환된다
    • access token과 refresh token은 encoded되어 있다. → jwt 사이트에서 decoded 할 수 있다 (feat. django SECRET_KEY)
    • access token : 사용자가 주민등록번호처럼 가지고 접속할 수 있게 하는 token이다.(즉, 사용자 인증과 비슷) + access 토큰은 만료일을 가지고 있다.
    • refresh token : access token이 만료가 되면 refresh token을 가지고 access token을 재발급 받을 수 있다.

 

  • 3) 장고에서 JWT를 이용해서 회원가입과 로그인을 하기위해서 user 만들기
    • 커스텀 유저 만들기 : 아래 링크 참고 (UserManager(BaseUserManager) / User(AbstractBaseUser) 함께 사용)
    • Customizing authentication in Django | Django documentation | Django
    • 커스텀 유저 모델을 → 장고 어드민 으로 등록해줘야 한다.

 

  • 4) 브라우저의 local storage에 백엔드에서 받은 토큰을 저장할 수 있다.
    • JWT에서 PAYLOAD 들어가는 logic customizing 하기 → id / email 정보 담기
    • views.py에서 : CustomTokenObtainPairView class 정의 + CustomTokenObtainPairView class안에serializer_class만 정의하면 알아서 처리
    • serializer_class정의 후 serializers.py에서 공식문서 참고 후 email token 부분 추가
    • 모두 추가 후 login → access token을 jwt에서 보면 email까지 customizing 된것을 볼 수 있다.
# TokenObtainPairView을 CustomTokenObtainPairView가 상속받는다.

class CustomTokenObtainPairView(TokenObtainPairView):
    serializer_class = CustomTokenObtainPairSerializer
# serializer.py

class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):

    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)

        token['email'] = user.email

        return token

 

 

 

 


 

[Frontend]

 

- 초기 설정 (https://wonprogrammer.tistory.com/76 참고)

  • 1) 새로운 front파일을 만들어 사용자에게 보여줄 .html 파일을 만들어 준 뒤 .js 파일을 넣어준다.
  • 2-1) 백엔드 서버를 불러올 .js 파일을 만들어 준다.
    • 2-1-1) 불러오기 전, 다른 도메인에서 요청을 보낼땐 별도의 허용이 필요하다. 따라서 백엔드 서버에서 cors 허용해주기
    • 2-1-2) pip install django-cors-headers
    • 2-1-3) 허용한 cors → Insatalled App에 선언
    • 2-1-4) MIDDLEWARE 에 'corsheaders.middleware.CorsMiddleware' 선언
    • 2-1-5) 마지막에 추후 Domain에 적용하기 위해 → CORS_ALLOW_ALL_ORIGINS = True 추가해주기

 

 

 

 

 

 

 

 

 

 

 

 

저작자표시 비영리 변경금지 (새창열림)

'woncoding > TIL' 카테고리의 다른 글

TIL | 10.28.금 [Django : DRF]  (0) 2022.10.31
TIL | 10.27.목 [Django : DRF]  (0) 2022.10.28
TIL | 10.25.화 [Django : DRF]  (0) 2022.10.25
TIL | 10.24.월 [Django : DRF]  (0) 2022.10.24
TIL | 10.21.금 [머신러닝 / Django]  (0) 2022.10.24
    'woncoding/TIL' 카테고리의 다른 글
    • TIL | 10.28.금 [Django : DRF]
    • TIL | 10.27.목 [Django : DRF]
    • TIL | 10.25.화 [Django : DRF]
    • TIL | 10.24.월 [Django : DRF]
    _won_
    _won_
    Coding Practice blog

    티스토리툴바