[Django][심화] 3주차 체크리스트

손성수·2023년 4월 20일
0

Checklist

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


쿠키 세션 방식 로그인과 토큰 방식 로그인의 차이

쿠키 세션 방식은 서버측 저장소에 의존하는 한편
토큰 기반 로그인 은 세션 데이터의 서버측 저장소에 의존하지 않는다.

한가지의 계정으로 여러곳에 접속할시(pc,핸드폰 등) 세션을 어떻게 처리할것인가? 에 대한
직면을 해결하기 위한 token 방식 도입
토큰 방식은 일종의 주민등록증 형태이며
발급을 받으면, 사용자의 로컬 환경에 저장하여 인증절차를 거친다.



cookie와 Local Storage의 차이점

데이터 용량
cookie 4096 byte
local 5MB

만료

  • 쿠키는 만료가 존재하지만 로컬은 만료가 존재하지 않는다.

API
임의로 지정하기 위해서는 쿠키는 까다로우나, 로컬은 간편하다.



JWT의 구조

JSON WEB TOKEN
JWT 확인할 수 있는 사이트
헤더와 페이로드, 서명으로 나뉘어져 있으며
헤더에는 보통 타입과 요청방식
페이로드는 사용자의 추가 데이터 (이름,이메일등등)
서명은 토큰의 무결성을 확인하며, 이에 장고 시크릿키를 통해 무결성을 검증할 수 있다.



JWT를 이용해서 회원가입과 로그인을 구현

SIMPLE JWT 공식 문서

pip install djangorestframework-simplejwt
------------------------------------------------------------------
settings.py
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    )
}
------------------------------------------------------------------
settings.py
INSTALLED_APPS = [
    ...
    'rest_framework',
    'rest_framework_simplejwt',
    'user',
]
------------------------------------------------------------------
app urls.py
from django.urls import path
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'),
]
settings.py
AUTH_USER_MODEL = 'user.User'
app.views.py

from rest_framework import status
# 연결상태 전송 헤더
from rest_framework.views import APIView
# API관련 클래스 상속 헤더
from rest_framework.response import Response
from .serializer import UserSerializer
# 사용자 정의 UserSerializer 모델 import

class UserView(APIView):
    def post(self,request):
        serializer = UserSerializer(data=request.data)
        #serializer를 통한 데이터 저장
        if serializer.is_valid():
            serializer.save()
            return Response({"message":"가입완료"},status=status.HTTP_201_CREATED)
        return Response({"message":f"${serializer.errors}"},status=status.HTTP_400_BAD_REQUEST)
app.serializer.py

from rest_framework import serializers
from .models import User

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = "__all__"

    def create(self, validated_data):
        user = super().create(validated_data)
        # 부모 클래스의 create메서드를 호출
        # 인자값을 전달하고 반환값을 user 변수에 담는다.
        password = user.password
        user.set_password(password)
        # 비밀번호 복호화
        user.save()
    def update(self, instance, validated_data):
        ...(create메서드와 동일)


로컬스토리지에 백엔드에서 받은 토큰을 저장

async function handleLogin() {
    const email = document.getElementById("email").value
    const password = document.getElementById("password").value
    // HTML 의 각 ID값의 데이터 저장
    
    const response = await fetch("http://127.0.0.1:8000/users/api/token/", {
        // fetch post 통신이 완료될때까지 기다리고, api에서는 세션의 토큰을 반환한다.
        headers: {
            'content-type': 'application/json',
        },
        method: 'POST',
        body: JSON.stringify({
            "email": email,
            "password": password,
        })
    })
    const response_json = await response.json()
    localStorage.setItem("access", response_json.access);
    localStorage.setItem("refresh", response_json.refresh);
    // 각 토큰을 로컬 스토리지에 저장


백엔드로 토큰값을 보내기

  • 아래 코드를 통해 인증된 사용자인지 구분할 수 있게된다.
async function handleMock() {

    const response = await fetch("http://127.0.0.1:8000/users/mock/", {
        headers: {
            'Authorization': "Bearer " + localStorage.getItem("access")
        },
        method: 'GET',
    })
    console.log(response)
}
profile
더 노력하겠습니다

0개의 댓글

관련 채용 정보