먼저 비밀번호 암호화와 토큰 발행에 활용되는 라이브러리와 모듈을 임포트 해온다.
import json
import bcrypt
import jwt
from westagram.settings import SECRET_KEY
from .models import Account
from django.views import View
from django.http import JsonResponse, HttpResponse
account앱에서 들어가서 views.py 에서 SignUpView 클래스에서 작성을 해야한다.
사용자에게서 받은 비밀번호를 그대로 DB에 넣으면 보안상 문제가 되므로 암호화해서 저장해야한다. 사용자에게 받은 비밀번호를 byte타입으로 인코딩해주고, 인코딩 한 값을 다시 hash값으로 암호화해준다.
DB에 이 값을 집어 넣을때는 다시 디코딩해서 문자열로 변환해서 저장한다.
class SignUpView(View):
def post(self, request):
data = json.loads(request.body)
try:
if Account.objects.filter(email = data['email']).exists(): # 존재하는 이메일인지 확인
return HttpResponse(status=400)
#==== 비밀번호 암호화====#
password = data['password'].encode('utf-8') # 입력된 패스워드를 바이트 형태로 인코딩
password_crypt = bcrypt.hashpw(password, bcrypt.gensalt()) # 암호화된 비밀번호 생성
password_crypt = password_crypt.decode('utf-8') # DB에 저장할 수 있는 유니코드 문자열 형태로 디코딩
#====================#
Account(
email = data['email'],
password = password_crypt # 암호화된 비밀번호를 DB에 저장
).save()
return HttpResponse(status=200)
except KeyError:
return JsonResponse({"message":"INVALID_KEYS"}, status = 400)
로그인 뷰에서는 사용자가 입력한 비밀번호가 db에 있는 사용자 이메일과 매칭되는 비밀번호와 일치하는지 확인을 해야한다.
만약 일치한다면 토큰을 발행해서 http응답에 같이 넘겨주면 된다.
class SignInView(View):
def post(self, request):
data = json.loads(request.body)
try:
if Account.objects.filter(email = data['email']).exists() :
user = Account.objects.get(email = data['email'])
#---------비밀번호 확인--------#
# 사용자가 입력한 비밀번호를 인코딩하고, 사용자의 이메일과 매칭되는 DB의 비밀번호를 찾아와서 인코딩. 이 두 값을 bcrypt.checkpw로 비교하면 됨
if bcrypt.checkpw(data['password'].encode('utf-8'), user.password.encode('utf-8')) :
#----------토큰 발행----------#
token = jwt.encode({'email' : data['email']}, SECRET_KEY, algorithm = "HS256")
token = token.decode('utf-8') # 유니코드 문자열로 디코딩
#-----------------------------#
return JsonResponse({"token" : token }, status=200) # 토큰을 담아서 응답
else :
return HttpResponse(status=401)
return HttpResponse(status=400)
except KeyError:
return JsonResponse({"message":"INVALID_KEYS"}, status = 400)