본문 바로가기
django/django REST Framework

2021.05.26 DRF JWT 인증방식 로그인, 회원가입

by 해맑은 코린이 2021. 5. 26.

2021.05.26 JWT 인증방식 로그인, 회원가입_정리노트

 

진ㄴㄴ...짜 오랜만 관련 자료도 많이 없고 내가 아직 라이브러리의 깃허브만 보고는 혼자 이해하며 커스텀할 수가 없어서... 진짜 미루고 미뤘다.

 

다행히 완전히 백엔드에서의 처리는 할 수 없었지만, 결국 나는 리액트와 연동하여 프로젝트를 꾸리는 것이 목표이기 때문에 내 고집은 잠시 접어두고 여러 곳을 뒤지다 결국 정말 친절한 분의 블로그를 보고 따라했다... 너무너무 감사합니다...

 

https://velog.io/@hyeon4137/React-DRF-API%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-velog-%EB%94%B0%EB%9D%BC-%EB%A7%8C%EB%93%A4%EC%96%B4%EB%B3%B4%EA%B8%B0-2%EC%9E%A5

 

React, DRF API를 이용한 velog 따라 만들어보기 2장

DRF의 JWT(JSON Web Token)의 인증방식을 통해 로그인과 회원가입 ,

velog.io

 

보통 다들 어려운 부분만 설명하고 전체코드를 깃허브로 올려놓으신분이 많았는데,,, 내 기준 정말 처음부터 끝까지 같이 해보는 블로그가 필요했다.. 다시한번 간접적으로 감사드립니다... 흑흑...

 


 

쨋든 정말 많이 헤메다 보니 코드를 치기 전에 여러 가지들의 개념을 먼저 혼자 정리해보려함.

 

일단 나를 오래 괴롭혔던, 회원가입, 로그인 관련 장고의 라이브러리를 정리를 먼저 해보자.

 

 

 

 

 

all-auth

https://github.com/pennersr/django-allauth

장고에서 제공하는 라이브러리로, 인증, 등록, 계정 관리 및 여러 소셜 계정 인증 까지 모두 할 수 있는 라이브러리다.

보통 장고에서  ( rest API 형태로 만들려면, 따로 프론트딴에서의 처리 필요. ) 소셜 인증이 필요로 할 때에는 거의 이 라이브러리를 사용한다고 한다. 

 

urlpatterns = [ 
   
    path('accounts/', include('allauth.urls')), 
    
]

 

이미지 출처 - https://whatisthenext.tistory.com/129

 

 

이 라이브러리를 설치하고, url 상에서 include 를 통해 받아오기만 하면, 여기서 제공하는 여러가지의 기능을 사용할 수 있다.

또한 여러 소셜 매체 로그인을 provider 를 통해서 제공하고, 이는 Oauth 인증을 통해 인증된 고객에게만 서비스를 제공할 수 있도록 한 것이다.

 

출처로 가져온 이미지에서 보면, accounts 뒤에 붙는 url로 여러가지 기능들이 구현되어 있어 우리는 해당 url 로 가면 해당 기능들을 사용할 수 있는 것을 볼 수 있다.

 

 

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites',
   
    # all-auth social login
     'allauth.socialaccount',
     'allauth.socialaccount.providers.github',
     'allauth.socialaccount.providers.google',
    
 
    
     
]

 

provider 를 쓸 수 있는 방법은 settings.py 에 있는 INSTALLED_APPS 에  allauth.socialaccount.providers.소셜앱이름

 

을 적어주면 된다. 제공하는 소셜앱들은 거의 대부분 있으니까 공식문서에서 참고해서 쓰면 될 것 같다!

 

https://medium.com/@pratique/social-login-with-react-and-django-i-c380fe8982e2

이를 프론트딴에 아예 못쓰는건 당ㅇㅇ연히 아니고, react 의 react-google-login  의 패키지와 drf 의 rest-auth 와 함께 쓰면 된다고 하는데, 음..^^ 일단 위의 링크는..올려놓지만 영어인데다가 나는 개인적으로 깃허브를 다 뜯어서 봤는데도 머선 말인지 이해 못해서 이 방법은 패쓰했다...^^ ㅎ...

 

 

아 그리고 여기서 rest-auth 라는 라이브러리가 또 나오는데, 이 라이브러리는 현재 중단된 상태다. ( 마지막 커밋 4년전.. )

dj-rest-auth 를 대신 쓰면 될 것 같다. 

 

 

https://dj-rest-auth.readthedocs.io/en/latest/introduction.html

 

dj-rest-auth

사용자 등록 및 인증 작업을 처리하는 REST API end porint 의 집합. 여기서 엔드 포인트란 API 가 서버에서 리소스에 접근할 수 있도록 가능하게 하는 URL 을 뜻한다. 이 라이브러리에서도 회원가입. 로그인/ 로그아웃 등을 지원한다.  이 때 dj_rest_auth.registration 를 사용하여 소셜 인증에 관련된 로직을 작성할 수 있다.

 

https://medium.com/chanjongs-programming-diary/django-rest-framework%EB%A1%9C-%EC%86%8C%EC%85%9C-%EB%A1%9C%EA%B7%B8%EC%9D%B8-api-%EA%B5%AC%ED%98%84%ED%95%B4%EB%B3%B4%EA%B8%B0-google-kakao-github-2ccc4d49a781

 

이 블로그를 보면서 따라했는데.. 이것도 역시 실패 ㅎㅁㅎ.. 흑흑.. 뷰가 너무 어려웠... 흑흑.. 꼭 라이브러리를 통해서 나도 다 이해하고 커스텀해서 쓸 수 있었으면 좋겠다..

 

 

이들을 따로 쓰는 곳도 있고, 둘 다 써서 구현하는 것도 있어서 많이 헷갈려서 이참에 정리.. 해당 라이브러리들은 서로 맞물려 있어서 더욱 각각 라이브러리들이 무슨 기능들이 있는지 더 헷갈렸던 것 같다.

 

이미지 출처 - https://code4human.tistory.com/83

 

 

다른 분의 블로그를 들어가면 잘 정리되어 있는데, 여러 번 삽질하다 보니 이제 잘 구분이 된다. rest-auth 또한 all-auth에 의존하는 라이브러리라고 한다. 또한 all-auth 도 장고에서 기본으로 제공되는 contrib.auth 에 의존한다하니, 똑똑한 분들은 꼭.. 같이 잘 써봤으면 좋겠다 ㅎㅁㅎ.. 그리고 저한테도 많이 공유..해주세요..흑흑 

 

 

 

근데 인증 관련 구현 글을 읽다보면 아직 익숙치 않은 용어들이 많이 등장한다... 

 

일단 완ㄴㄴㄴㄴ전히 암것도 모르는 내 입장에서는 cookie 부터 session, access_token, refresh_token 등등 ...

 

즈어어엉엉말... 모르는게 한참임... 

 

서버 관련이라 진짜 여러 글들을 읽으면서 아아.. 이런거구나 했는데 유용했던 블로그 하나를 또.. 긁긁..

 

https://tansfil.tistory.com/58?category=475681 

 

쉽게 알아보는 서버 인증 1편(세션/쿠키 , JWT)

앱 개발을 처음 배우게 됐을 때, 각종 화면을 디자인해보면서 프론트엔드 개발에 큰 흥미가 생겼습니다. 한때 프론트엔드 개발자를 꿈꾸기도 했었죠(현실은 ...) 그러나 서버와 통신을 처음 배

tansfil.tistory.com

 

 

 

https://tansfil.tistory.com/59?category=475681 

 

쉽게 알아보는 서버 인증 2편(Access Token + Refresh Token)

안녕하세요! 이전 포스팅에는 크게 세션/쿠키 인증, 토큰 기반 인증(대표적으로 JWT)에 대하여 알아보았습니다. 저희가 앱, 웹 혹은 서버 개발을 하면서 꼭 사용하게 되는 인증(Authorization)은 아주

tansfil.tistory.com

 

 

https://tansfil.tistory.com/60?category=475681 

 

쉽게 알아보는 서버 인증 3편(SNS 로그인, OAuth 2.0)

안녕하세요 여러분. 오늘은 "쉽게 알아보는 인증"의 마지막 편인 SNS 로그인 과 OAuth에 대해 써보려고 합니다. 만일 SNS 로그인을 한 번이라도 구현해보려고 하셨다면, OAuth을 한 번은 들어보셨을

tansfil.tistory.com

 

 

 

너무너무 쉽게 설명을 잘해주셔서 3개를 몽땅 가져왔다. 최고... 

3장을 전부 읽으면, 어느정도 내가 오늘 사용할 JWT 인증 방식과 더불어 서버가 어떻게 보안적인 요소를 사용해서 사용자의 인증을 하는지 개괄적으로 알 수 있을 것이다. 

 

 

 

https://d2.naver.com/helloworld/24942

 

그리고 지금은 대부분 OAuth 2.0 을 사용하지만 , OAuth 에 대해서 좀 더 자세한 글은 또 복붙..해왔음 ㅎㅁㅎ

여기서 복잡한거 다 빼고 그냥 내 기준 중요한 한 문장을 꼽자면, OAuth와 로그인은 반드시 분리해서 이해해야 한다는 점...! OAuth 는 허가의 영역이지, 로그인의 영역은 아니라는 점은 꼭 새겼다!!

 

 

 

 


 

 

서버 인증에 관한 개념을 정말 모르다보니, 개념정리만 해도 참고할 블로그를 넘무 많이 들고 온 것...같군 .. 그래도 이 개념들은 어쭙잖은 내가 정리해서 하는 것보단 이미 친절하고 멋진 분들이 적은 관련 글을 천천히 읽어보는게 모두에게 이로울 것 같아서 오늘은 복붙으로 시작 ㅎㅁㅎ ! 멋진분들 다들... 모르는 분들이지만.. 존경하고 감사합니다..ㅎ그흐긓그흐극

 

 


 

 

 

진짜 이제 맨 처음에 올렸던 velog 의 글을 보고 같이 따라하며 개념 정리!

 

내가 쓸 방법은 restframework 의 jwt 인증방식을 통한 로그인과 회원가입을 먼저 백엔드딴에서 구현하는 것을 이 포스팅에 담을 예정!

 

우리는 이미 저번 포스팅에서 django 와 djagorestframework를 설치했으니까, 우리가 설치할 거는 오늘

 

 

pip install djangorestframework-jwt

 

 

하나 되시겠다! 이거는 drf에서 토큰발행을 위한 패키지이다. 

 

 

이제 settings.py 로 가서 여러 가지 설정을 해줍씨다.

 

 

 

settings.py

 

settings.py 

 

 

해당 라이브러리를 설치해주고, settings.py 에도 적어준다!

 

from datetime import timedelta
from pathlib import Path
import os
import json
import sys


BASE_DIR = Path(__file__).resolve().parent.parent



ROOT_DIR = os.path.dirname(BASE_DIR)

# secrets.json 경로 ==> BASE_DIRS 의 경로는 현재 생성해준 프로젝트의 경로를 가리킨다.

SECRET_BASE_FILE = os.path.join(BASE_DIR, 'secrets.json')

#secret.json 읽기
secrets = json.loads(open(SECRET_BASE_FILE).read())
for key, value in secrets.items():
    setattr(sys.modules[__name__], key, value)



또한 장고의 시크릿키나, API 를 쓸 때 client_id, secret_key 등은 노출되면 안되기 때문에 따로 secrets.json 으로 분리해서 적어주었다. 경로는 BASE_DIR 의 밑의 경로. 즉 여기서 BASE_DIR 가 가리키는 곳은 장고 프로젝트이므로, 프로젝트 바로 밑에 secrets.json 이 있다고 해주었다. 

 

 

REST_FRAMEWORK = {
    # 인증된 유저만 헤더에 access token 을 포함하여 유효한 유저만이 접근이 가능해지는 것을 디폴트로. permission_classes 변수 설정할 필요가 없음.
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',  # 인증된 회원만 엑세스 허용
        'rest_framework.permissions.AllowAny',         # 모든 회원 액세스 허용
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication', #api 실행시 인증할 클래스 정의
    ),
}

 

 

#JWT 환경 설정
REST_USE_JWT = True

from datetime import timedelta

# 추가 설정 부분

SIMPLE_JWT = {
   
   # 여기는 기본 세팅값
   
   'JWT_SECRET_KEY': SECRET_KEY,   # JWT 에 서명하는데 사용되는 시크릿키. 장고의 시크릿키가 디폴트.
   'JWT_ALGORITHM': 'HS256',       # PyJWT 에서 암호화 서명에 지원되는 알고리즘으로 마찬가지로 이것 또한 기본값.
   'JWT_VERIFY_EXPIRATION' : True, # 토큰 만료 시간 확인. 기본값 True.
    
   # 새로 커스텀한 옵션들
   
   'JWT_ALLOW_REFRESH': True,      # 토큰 새로고침 기능 활성화. 기본값 False.
   'JWT_EXPIRATION_DELTA': timedelta(minutes=30),     # datetime.timedelta 의 만료 시간. 기본값 seconds=300. 
   'JWT_REFRESH_EXPIRATION_DELTA': timedelta(days=3), # Refresh Token의 새로 고침 시간. 기본값 days=7
   'JWT_RESPONSE_PAYLOAD_HANDLER': 'accounts.custom_responses.my_jwt_response_handler'  #로그인 또는 새로 고침 후 반환되는 응답 데이터를 제어. 기본값은 {'token' : token } 인데 이건 나중에 우리가 따로 적어줄것임.
}

 

이 세팅은 https://jpadilla.github.io/django-rest-framework-jwt/ 해당 링크를 참고하였움! 추가적인 옵션들은 여기서 보면 될 것 같다!

 

 

 

그리고 이제 models.py 로 ㄱ ㄱ!

 

나는 블로그랑 다르게 원래 프로젝트에서 만들던 거에서 앱을 추가 설치를 해주었기 때문에, 헷갈릴 수도 있어서 먼저 내 프로젝트와 앱들의 경로는 

 

 

프로젝트에 accounts 와 backed 앱을 두개 만들어 주었고,  리액트의 frontend 폴더가 있다. 정리해야하지만, 지금 워낙 오류를 띄워서...^^ 무섭다...ㅎ 일단은 또 능력이 되면, accounts 랑 backend 도 같이 묶어주어야겠당

 

 

 

프로젝트/accounts/models.py

 

 

출처 - django 공식 문서

 

 

또 우리는 django 에서 User 를 가져와서 유저가 생성되면, receiver 데코레이터를 이용해서 자동으로 프로필을 생성하고, 프로필을 저장해준다.

 

 

프로젝트/accounts/admin.py

 

 

 

어드민에서 등록할 때, User, Profile 을 각각 등록해주어도 되지만, 여기서는 User 안에 디테일로 Profile 을 넣어줘서 좀 더 유저별로 한번에 프로필까지 보기 위해서 StackedInline 을 사용했다. 

 

출처 - django 공식문서

 

또 프로필 개체가 삭제 되지 않도록 can_delete 옵션을 False 로 작성해주었음!! ( 기본은 True )

 

 

verbose_name_plural 은 예전 포스팅에서 언급했었는데, 이름을 그냥 우리 맘대로 지어주기 위한것 ㅇㅇ 

 

그리고 우리가 쨋든간에 커스텀된 프로필 모델을 User 랑 연결시켜줬기 때문에, 기본적으로 django 에서 연결된 User 모델의 등록을 취소해주고, 그 다음에 우리의 User 모델과 UserAdmin 을 등록해주었다.

 

 

이렇게 하면 어드민 페이지에서

 

나는 기본언어를 settings 에서 한국어로 바꿨음

 

Users 로 들어가게 되면,

 

이렇게 Profile 이 인라인으로 잘 들어가게 된다. 여기서 궁금해서 can_delete 옵션을 True 로 주고 실행하니까 

 

 

요롷게 Profile 만 삭제할 수 있군. 나는 이렇게 안할거니까 다시 False 로 주자.

 

 

 

자!!!!!! 이제 serializer 로 간다!!!!!!!!!!!

 

 

프로젝트/accounts/serializers.py

 

 

오오.. 어렵다....ㅋㅋㅋㅋㅋㅋㅋ큐ㅠㅠ 그래도 흐름을 설명하자면, 

 

 

출처 - djago restframework-jwt github page

 

 

Userseirializer , Profileserializer 를 생성할 건데, 계정 생성 직후에 사용자에게 토큰을 반환하기 위해 수동으로 토큰을 생성하는 메소드들을 적어준 것이다.

 

그러고!!!!! 아까 settings.py 에 'JWT_RESPONSE_PAYLOAD_HANDLER': 'accounts.custom_responses.my_jwt_response_handler'

 

라고 우리가 따로 적어준다고 했었지!!

 

 

프로젝트/accounts/custom_responses.py

 

새로 custom_responses를 생성해주고, 

 

 

이렇게 적어줄 것이다. 이 기능은, 

 

출처 - djangorestframework jwt github page

 

 

요롷게 토큰 인증을 확장 시키는 거라네여 헣헣ㅎ 

 

 

자 이제 또!!!!!!!!! view 로 갑씨다!!!!!!!!!! 

 

프로젝트/accounts/views.py

 

 

여기서 우리는 view 를 두 가지 형태로 쓴 것을 볼 수 있는데, 

 

CBV 와 FBV 를 둘 다 썼다!

 

class based view 는 메소드( 클래스 안의 함수 ) 를 이용해서 각각의 Http method 를 정의하고, 

funtion based view 는 @api_view 라는 데코레이터를 이용해서 Http method 를 정의한다.

 

출처 - django rest framework 공식 문서

 

 

출처 - django rest framework 공식 문서

 

 

 

DRF 에서는 API 를 만드는 방법이 총 5가지로 CBV, FBV, mixin,generics,viewSet 이렇게 있는데 viewSet 을 이용해서 진짜 편리하게 만들 수도 있고, 이렇게 CBV, FBV를 사용해서 유연한 API 를 만들 수 있다.

 

 

 

 

 

나머지 profile 업데이트와 우리가 아까 custom 한 token 인증 관련 view 또한 채워넣어준다.

 

 

마지막!!!!!!!!!!! 모든걸 url 로 연결 시켜주자!!!!!

 

프로젝트/urls.py

 

 

프로젝트/accounts/urls.py

 

 

자!!!!! 여기까지 모두 세팅이 끝났으니!!!!!!!!! 확인하러 가볼까 헿 ㅎㅁㅎ

 

 

http://localhost:8000/accounts/

 

 

 

http://localhost:8000/accounts/current/

 

 

 

이게 머선 129... 전부 권환 거부됨.. 하지만 이건 잘못된게 아니다. 우리는 설정을 할 때, 토큰을 인증받은 유저만 자신의 user 정보를 열람할 수 있는 권한을 부여한다고 했으므로! 또한 userlist 는 관리자를 제외하고는 아무도 볼 수 없어야 하는것도 당연 ㅇㅇ 메소드 또한 POST 로 우리가 아까 CBV 로 주었다. 나머지는 또 프론트를 같이 따라해보면서 추가로 설정할 부분은 다음 포스팅에서 또 적어보겠삼.

 

 

 


 

 

후!! 여기까지

https://velog.io/@hyeon4137/React-DRF-API%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-velog-%EB%94%B0%EB%9D%BC-%EB%A7%8C%EB%93%A4%EC%96%B4%EB%B3%B4%EA%B8%B0-2%EC%9E%A5

 

React, DRF API를 이용한 velog 따라 만들어보기 2장

DRF의 JWT(JSON Web Token)의 인증방식을 통해 로그인과 회원가입 ,

velog.io

 

이 분의 블로그의 2장을 순서대로 따라하면서 ( 너무 감사해서 한번 더 링크 첨부 ) 내가 궁금했던 부분들을 하나하나 다시 찾아가며 정리했다. 오늘은 실행보다는 개념 정리에 초점을 둔 만큼 이제 앞으로 프론트에서 헤멜 때 좀 더 어디서 헤메고 뭐가 잘못된 건지 짚어가면서 할 수 있었으면 좋겠어서 진짜 하나하나 거의 다 찾아가면서 정리해봤움!!!!!!!

 

그리고 혹시나 나보다 똑똑한 다른분들이 이 블로그를 본다면 여러 참고 자료들을 잘 활용해서 자신만의 REST API 를 만들 때 도움이 되었으면 하는 방면에서...ㅎㅁㅎ.. 그리고 꼭 같이 공유해주면 좋겠다는 나의 작은 소망 ㅎㅁㅎ 쨋든 이렇게 오늘은... 늦게 온만큼 역대급으로 조금 길게 적어보았다!!! 그러면 오늘도 빠잉!

'django > django REST Framework' 카테고리의 다른 글

2021.09.10 REST API HTTP Method  (0) 2021.09.10
2021.05.04 django restframework tutorial  (2) 2021.05.04

댓글