Framework/Django

DRF 심화과정 3주차

JM Lee 2023. 4. 23. 13:11
728x90

요약 : 공식문서 열심히 봐라, 

           토큰의 구조, 역할에 대해 확실히 이해해라.

           장고의 구성에 많이 신경써라

 

3주차 체크리스트

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

  • 세션방식은 모든 유저의 정보와 세션 정보를 서버에서 관리함
    1. 클라이언트에서 사용자의 인증 정보를 서버에 전달함(로그인 할 때 아이디, 비밀번호를 입력하면 그 값이 서버로 전달된다는 말)
    2. 서버는 인증을 처리한 뒤 해당 사용자에 대해 세션을 생성함
    3. 세션 정보는 서버에 저장되고 클라이언트는 세션 id를 받아 브라우저(쿠키)에 저장
    4. 클라이언트는 이후 요청에 대해 세션 id를 서버에 넘김
    5. 서버는 전달 받은 세션 id를 매치되는 저장 중인 세션 정보로 인증을 처리함
    6. 만약 세션 id가 만료되었을 경우 1번 과정부터 다시 이루어짐
  • 토큰방식은 토큰 정보를 서버에 저장하지 않음. 대표적인 방식으로 JWT(JSON Web Token)가 있음
    1. 클라이언트에서 사용자의 인증 정보를 서버에 전달(세션 방식과 동일)
    2. 서버는 인증 정보로 인증을 처리하고 (세션 대신) JWT를 생성하여 클라이언트에 전달
    3. 클라이언트는 JWT를 브라우저(localStorage)에 저장
    4. 클라이언트는 이후 이루어지는 요청에 JWT를 이용
    5. 서버는 JWT를 검증하여 인증을 처리
    6. JWT가 만료되면 토큰을 refresh 함
  • 세션방식의 단점은 매번 인증을 위해 데이터베이스에 질의를 거쳐야 한다는 것

 

2. 쿠키와 로컬 스토리지의 차이

  쿠키 로컬 스토리지
보내주는 것 이름, value, 사용 도메인, 만료 여부 이름, value/ 만료는 없음
요청 모든 요청이 서버로 감(회원가입 유리) 모든 요청은 아님
API 지정/설정 모름 매우 편리
저장 가능 공간 4096Byte 5MB

3. JWT 토큰 구조

Header : 자료구조, 타입

Body : 데이터

Verify Signature : 서명(시크릿 키를 이용한 암호문)

 

4. 장고에서 JWT를 이용해서 회원가입과 로그인 구현

우리는 simpleJWT를 사용할 것이기 때문에

pip install django djangorestframework djangorestframework-simplejwt -

URL, Views 먼저 설정(함수와 함수의 경로 미리 기획) - model 손 대기 - migrate

회원가입은 createsuperuser를 통해 관리자 아이디로만 우선 생성, 로그인 역시 마찬가지

 

5. 브라우저의 로컬 스토리지에 백엔드에서 받은 토큰 저장

# urls.py

path('api/token/', views.CustomTokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
# views.py

from users.serializers import CustomTokenObtainPairSerializer

class CustomTokenObtainPairView(TokenObtainPairView):
    serializer_class = CustomTokenObtainPairSerializer
    
# CustomTokenObtainPairSerializer이 토큰을 얻게 하는 명령어인듯

# 아래는 CustomTokenObtainPairSerializer에 대한 공식문서 내용 번역한 것

# TokenObtainPairView 및 TokenObtainSlidingView 뷰에서 생성되는
# 웹 토큰에 포함된 클레임을 사용자 지정하려면
# 원하는 뷰에 대한 하위 클래스와 해당 직렬화 프로그램에 대한 하위 클래스를 만듭니다.
# 표준 토큰 보기와 마찬가지로 하위 분류 보기에 대한 URL 경로도 포함해야 합니다.

 

6. 프론트에서 로컬 스토리지의 토큰을 헤더에 실어서 백엔드로 보내기

URL과 raw, JSON 을 잘 지킨 다음 아래와 같이 포스트맨에서 로그인을 해주면

access, refresh토큰이 나온다.

URL에는 꼭 슬래시(/)형식 urls.py와 맞게 찍어주기! 안 그러면 오류 남

async function handleSignin(){
    const email = document.getElementById("email").value
    const password = document.getElementById("password").value
    console.log(email,password)
    // const : 변하지 않는다는 함수
    // 변할 시 에러 발생
    // document == html(문서)
    // value값을 가져오기
    // async

    const response = await fetch('http://127.0.0.1:8000/users/signup/', {
        headers: {
            'content-type' : 'application/json',
            // 글 타입으로 JSon 형태를 받겠다
            // JWT 형식은 자바스크립트에서도 이어진다!

        },
        method: 'POST',
        body: JSON.stringify({
            "email" : email,
            "password" : password
            // JSon 형태이므로 반드시 쌍따옴표 쓰기
        })
        // stringfy = serialize
    })

    console.log(response)
}

 

7. 포스트맨에서 헤더에 토큰을 실어서 백엔드로 보내기

Key에는 Authorization, Value에는 Bearer '토큰' 형식으로 써줘야 한다.

 

8. 토큰의 만료기간 설정

# settings.py

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(hours=10),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=10),
}

9. 토큰이 만료될 때 REFRESH 토큰 다시 받아오기

포스트맨에서 받은 refresh 토큰 이용하면 됨. 그것을 마찬가지로 Bearer 'refresh토큰' 해주면 새 토큰이 나타난다.