[django] 비밀번호 암호화 및 토큰 발행

hyeyul·2020년 5월 24일
0

Django

목록 보기
7/8

1. 모듈 import

먼저 비밀번호 암호화와 토큰 발행에 활용되는 라이브러리와 모듈을 임포트 해온다.

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

2. 회원가입 View - 비밀번호 암호화

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)

3. 로그인 view - 비밀번호 확인 및 토큰 발행

로그인 뷰에서는 사용자가 입력한 비밀번호가 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)

0개의 댓글