일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- promise
- django
- 파이썬리스트컴프리헨션
- bcrypt
- RESTfulAPI
- 인터넷 네트워크
- decorator
- clone coding
- 백준
- 코딩테스트파이썬
- 리스트컴프리헨션
- 파이썬입출력
- 해시충돌
- *args
- JavaScript
- 알고리즘
- wecode
- DP
- QuerySet
- 윈도우우분투듀얼부팅
- 인증인가
- 파이썬문법
- docker
- 파이썬
- Python
- 자바스크립트
- 자료구조
- clone-coding
- CSS
- **kwargs
- Today
- Total
개발기록장
[Django] 인스타그램 클론 코딩(2) - 로그인 기능 구현 본문
[이전 글]
[Django] 인스타그램 클론 코딩(1) - 회원가입 기능 구현
[Django] 인스타그램 클론 코딩(1) - 회원가입 기능 구현
[다음 글] devvvyang.tistory.com/41 [Django] 인스타그램 클론 코딩(2) - 로그인 기능 구현 인스타그램은 전화번호, 사용자 이름, 이메일 중 하나와 패스워드로 로그인을 할 수 있다. 이를 views.py에 LoginView..
devvvyang.tistory.com
[다음 글]
[Django] 인스타그램 클론 코딩(4) - Authorizarion Decorator 만들고 활용하기
[Django] 인스타그램 클론 코딩(3) - Authorization Decorator 만들고 활용
[이전 글] devvvyang.tistory.com/41 [Django] 인스타그램 클론 코딩(2) - 로그인 기능 구현 인스타그램은 전화번호, 사용자 이름, 이메일 중 하나와 패스워드로 로그인을 할 수 있다. 이를 views.py에 LoginView..
devvvyang.tistory.com
인스타그램은 전화번호, 사용자 이름, 이메일 중 하나와 패스워드로 로그인을 할 수 있다.
이를 views.py에 LoginView에 작성하였다.
views.py
- LoginView 클래스에서 로그인 기능 처리
import jwt
import json
import bcrypt
from django.views import View
from django.http import JsonResponse
from django.db.models import Q
from .models import User
from my_settings import SECRET
class LoginView(View):
def post(self, request):
data = json.loads(request.body)
email = data.get('email', None)
name = data.get('name', None)
phone = data.get('phone', None)
password = data.get('password', None)
# key error check
if not (password and (email or name or phone)):
return JsonResponse({'message': 'KEY_ERROR'}, status=400)
# valid user check
if User.objects.filter(Q(email=email) | Q(name=name) | Q(phone=phone)).exists():
user = User.objects.get(Q(email=email) | Q(name=name) | Q(phone=phone))
# password check
if bcrypt.checkpw(password.encode('utf-8'), user.password.encode('utf-8')):
# JSON Web Token
token = jwt.encode({'user_id': user.id}, SECRET['secret'], algorithm='HS256')
return JsonResponse({'message': 'SUCCESS', 'access_token': token}, status=200)
return JsonResponse({'message': 'INVALID_PASSWORD'}, status=401)
return JsonResponse({'message': 'INVALID_USER'}, status=401)
-
http request에서 이메일(email), 사용자 이름(name), 전화번호(phone) 중 하나와 비밀번호(password)를 입력받으면 로그인이 되도록 구현하였다.
-
로그인 시 이메일이나 사용자 이름, 전화번호 중 하나만 일치하면 해당하는 user를 get하고 비밀번호 일치 여부를 체크하도록 구현했다.
-
password는 회원가입 시 암호화 된 상태로 저장되게 구현했기 때문에(bcrypt.haspw() 사용), 비밀번호가 일치하는지 체크하는 과정에서 bcrypt.checkpw() 메소드를 이용하였다.
-
로그인에 성공을 하면 해당 user의 인가를 위해 JSON Web Token을 발행하고, respone에 전달한다.
발생할 수 있는 에러와 처리 방법
1. key error
(생략..)
class LoginView(View):
def post(self, request):
data = json.loads(request.body)
email = data.get('email', None) # request body에 'email'이라는 키 값이 없으면 None으로 처리
name = data.get('name', None) # request body에 'name'이라는 키 값이 없으면 None으로 처리
phone = data.get('phone', None) # request body에 'phone'이라는 키 값이 없으면 None으로 처리
password = data.get('password', None) # request body에 'password'이라는 키 값이 없으면 None으로 처리
# key error check
if not (password and (email or name or phone)):
return JsonResponse({'message': 'KEY_ERROR'}, status=400)
(생략..)
-
인스타그램 로그인 시 email, name, phone 중 하나의 값만 입력해야 하기 때문에, 입력하지 않은 값은 default로 None값을 세팅하도록 구현하였다.
-
http request body에서 views.py에 명시된 키값들을 전달받지 못하면 key error가 발생하는데, try-except로 처리할 수도 있지만
-
여기서는 들어오지 않은 값들이 None인 것을 이용하여 email, name, phone, password 이 4개의 값이 모두 None이 될 때 key error를 return하여 에러 처리를 구현하였다.
2. 계정 정보 또는 비밀번호가 일치하지 않을 때
위에서 말했듯, email 또는 name 또는 phone 값 중 하나가 DB에 저장된 user의 정보와 일치하는게 있다면, 해당 user 정보를 가져온다. (Django의 Q 메소드를 사용해서 간편하게 로직을 구현할 수 있었다)
(생략..)
class LoginView(View):
def post(self, request):
(생략..)
# valid user check
if User.objects.filter(Q(email=email) | Q(name=name) | Q(phone=phone)).exists():
user = User.objects.get(Q(email=email) | Q(name=name) | Q(phone=phone))
# password check
if bcrypt.checkpw(password.encode('utf-8'), user.password.encode('utf-8')):
# JSON Web Token
token = jwt.encode({'user_id': user.id}, SECRET['secret'], algorithm='HS256')
return JsonResponse({'message': 'SUCCESS', 'access_token': token}, status=200)
return JsonResponse({'message': 'INVALID_PASSWORD'}, status=401)
return JsonResponse({'message': 'INVALID_USER'}, status=401)
(생략..)
-
기존 user와 일치하는 user가 없다면, 유효하지 않은 계정이므로 401 code로 에러를 반환하도록 구현하였다.
-
일치하는 user가 있다면 password가 같은지 체크하고 비밀번호가 틀릴 경우, 마찬가지로 401 code와 에러를 반환한다.
-
사실 로그인 시 계정(여기서는 이메일, 사용자 이름, 전화번호 중 하나)이 틀렸거나 비밀번호가 틀렸을 때, 두 경우를 나눠서 에러 메세지를 반환하지 않는다. 해킹 위험이 증가하기 때문이다. (현업에서는 return도 HttpResponse로 401 코드만 준다)
하지만 여기서는 front-end와의 원활한 작업을 위해 각 경우에 대해 에러처리를 따로 해줬다.
'TIL > Django' 카테고리의 다른 글
[Django] 인스타그램 클론 코딩(4) - 게시물과 댓글 C.R.U.D (RESTful API) (0) | 2021.02.09 |
---|---|
[Django] 인스타그램 클론 코딩(3) - Authorization Decorator 만들고 활용하기 (1) | 2021.02.08 |
[Django] 인스타그램 클론 코딩(1) - 회원가입 기능 구현 (0) | 2021.02.02 |
[Django] ManyToManyField 설정과 데이터 조회 방법 (0) | 2021.01.27 |
[Django] QuerySet 메소드 정리 (2) - CRUD (5) | 2021.01.25 |