-
[DJANGO] 인증과 인가 (3) : 로그인 구현DEV/🟢 DJANGO 2021. 8. 27. 21:22
토큰(서버입장권)을 주는 서버와 프론트엔드 로그인 구현
로그인구현에 필요한 로직을 생각해보자.
서버의 관점에서 로그인은 사용자가 입력한 이메일과 비밀번호를
회원가입 로직을 통해 데이터 베이스에 들어온 데이터와 비교해서 맞으면 통과시키고 맞지않으면 통과시키지 않는 것이다.
비교와 통과를 어떻게 할 것인가가 핵심이다.
따라서, 데이터 베이스를 비교하기 위해선 get 이 아닌 post 메소드를 이용해서 데이터를 받고 비교하는 과정을 거치고
일치할 경우, 토큰을 주는 과정이 필요하다.
class Login(View): def post(self, request): try: data = json.load(request,body) email = data['email'] password = data['password'] if not User.objects.filter(email = email).exists(): return JsonResponse({"MESSAGE": "INVALID_USER"}, status=401) ================================================================ 암호화된 비밀번호를 체크해서 맞지않으면 메세지 + 토큰 생성 후 발급 ================================================================ except KeyError: return JsonResponse({"MESSAGE":"KEY_ERROR"}, status=400)
암호화된 비밀번호를 체크해서 맞지 않으면 메시지를 주는 로직을 짜보자.
이때 생각해야할 것은 암호화된 비밀번호의 위치다.
Users 테이블의 get로 걸러진 email에서 하나만! 꺼내는 것을 파악하는 것이 중요하다.
user = User.objects.get(email = email)
암호화된비밀번호를 체크할때는 bcrypt를 사용해서 체크하자, 이때 인코딩 후 바이트로 체크해야한다.
bcrypt.checkpw( password(인코딩), hashed(인코딩) )
>> True or False
if not bcrypt.checkpw(password.encode('utf-8'), user.password.encode('utf-8')): return JsonResponse({"MESSAGE":"NOT CORRECT!"}, status = 401)
토큰까지 발행해주자 이때 필요한 라이브러리는 jwt이다.
로그인한 id = 𝑿인 user 에게 토큰을 발행하는 것이다.
이미 user에는 이메일로 로그인한 객체가 있다. 이때의 id값을 가져오면 된다.
ticket = jwt.encode({'id': user.id}, 'SECRET_KEY', algorithm = 'HS256' ) return JsonResponse({"MESSAGE":"SUCCESS", "TOKEN": ticket}, status=200)
🔥 왜 id값으로 설정했을까?
유저아이디는 단순한 숫자이기때문에 데이터베이스에 접근하지 않는 한 의미없는 데이터라고 할 수 있다.
유저아이디를 포함해서 jwt를 발행하고 복구화해서 이후에 인가과정에서 사용한다.
더보기인코딩된 값으로 들어가는 jwt 이때 디코드를 하게 된다면?
jwt.decode( ticket, 'SECRET_KEY', algorithm = 'HS256' )
>> { 'id' : '로그인한 id값' },
🔥 SECRET_KEY
왜 시크릿키를 따로 보관하게 되는 것일까?
DATABASES 에 대한 정보는 MySQL에 대한 접근권한을 따로 보관하고
SECRET_KEY는 장고 공식문서에서 찾아보니 장고 프로젝트에서의 보안기능을 수행한다고 한다.
컴퓨터 로그인 시 비밀번호를 치는 것과 같은 원리라고 생각하자. 매우 프로젝트 시작에 있어 중요한 값이다..
완성된 Login 구현
from my_settings import SECRET_KEY class Login(View): def post(self,request): try: data = json.loads(request.body) email = data['email'] password = data['password'] if not User.objects.filter(email = email).exists(): return JsonResponse({"MESSAGE": "INVALID_USER"}, status=401) user = User.objects.get(email = email) if not bcrypt.checkpw(password.encode('utf-8'), user.password.encode('utf-8')): return JsonResponse({"MESSAGE": "INVALID_PASSWORD"}, status=401) ticket = jwt.encode({'id':user.id}, SECRET_KEY, algorithm='HS256') return JsonResponse({"MESSAGE":"SUCCESS", "TOKEN": ticket}, status=200) except KeyError: return JsonResponse({"MESSAGE":"KEY_ERROR"}, status=400)
'코딩 > 🟢 DJANGO' 카테고리의 다른 글
[REST API] Path Prameter & Query Prameter (0) 2021.09.13 [API] REST API (0) 2021.09.12 [DJANGO] 인증과 인가(2) : 비밀번호 암호화 (0) 2021.08.27 [DJANGO] 인증과 인가(1) : 회원가입 구현하기 (0) 2021.08.26 [DJANGO] CRUD: POST & GET 로직 (0) 2021.08.22