[Westagram] : 회원가입 비밀번호 암호화 적용

과제


1. 구현 전 생각

인증/인가 때 bcrypt를 이용하여 암호화하는 과정을 배워서 적용하면 되겠다!


2. 구현

class SignupView(View) :
    def post(self, request) :

        try :

            data = json.loads(request.body)
        
            email     = data['email']
            password  = data['password']
            birthday  = data.get('birthday', None)

            if User.objects.filter(email=email).exists() :
                return JsonResponse({'message':'기존재 이메일입니다.'}, status=400)
            
            user = User.objects.create(
                email     = email,
                password  = password,
                name      = data['name'],
                telephone = data['telephone'],
                birthday  = birthday
            )
            
            user.full_clean()
            
            user.password = user.password.encode('utf-8')
            user.password = bcrypt.hashpw(user.password, bcrypt.gensalt())
            user.password = user.password.decode('utf-8')

            user.save()

            return JsonResponse({'mesage':'SUCCESS'},status=201)
        
        except KeyError:
            return JsonResponse({'message':'KEY_ERROR'}, status=400)

        except ValidationError as msg :
            if User.objects.filter(email=email).exists() :
                User.objects.filter(email=email).delete()

            messages = ''

            for message in msg.messages :
                messages += message

            return JsonResponse({'message':messages}, status=400)

3. 멘토님 피드백

구현 후, 피드백을 받는 과정에서 validators.py를 이용하여 full_clean()을
이용하는 것 보다, 한 파일에서 관리해서 폭포수처럼 코드를 읽을 수 있게
하는 것이 좋다고 하셨다.

그래서 validators.py 삭제 -> 해당 코드 views.py로 이관 -> models.py변경
과정이 발생했다.


4. 최종


4-1. models.py

모델의 경우, 생성/수정시간은 어디든 들어가야한다는 국룰에 의해
TimeStampModel을 만들었다.

해당 모델은 models.Model을 상속 받았기 때문에

다른 모델 선언 때 이 모델을 상속시켜주면 됨

생일도 other_info로 변경

from django.db import models

class TimeStampedModel(models.Model) :
    created_at = models.DateTimeField(auto_now_add=True)
    modified_at = models.DateTimeField(auto_now=True)

    class Meta :
        abstract = True

class User(TimeStampedModel) :
    email = models.EmailField(max_length=30, unique=True)
    password = models.CharField(max_length=500)
    name = models.CharField(max_length=20, null=True, blank=True)
    telephone = models.CharField(max_length=20, null=True, blank=True)
    other_info = models.CharField(max_length=100, null=True, blank=True)

    class Meta :
        db_table = 'users'

4-2 views.py

class SignupView(View) :
    def post(self, request) :
        try :
            data = json.loads(request.body)

            email      = data['email']
            password   = data['password']
            name       = data.get('name', None)
            telephone  = data.get('telephone', None)
            other_info = data.get('other_info', None)

            email_reg = r"^[\w+-\_.]+@[\w]+\.[\w]+$"

            if not re.match(email_reg, email) :
                return JsonResponse({'message':'Email Validation Error'}, status=401)

            password_reg = r"^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[!@#$%^&*()_+=-])[a-zA-Z0-9!@#$%^&*()_+=-]{8,}$"

            if User.objects.filter(email=email).exists() :
                return JsonResponse({'message':'기 존재 이메일입니다.'}, status=401)

            if not re.match(password_reg, password) :
                return JsonResponse({'message':'Password Validation Error'}, status=401)
                    
            User(
                email      = email,
                name       = name,
                telephone  = telephone,
                other_info = other_info,
                password   = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
            ).save()

            return JsonResponse({'message':'HIHI'}, status=201)

        except KeyError :
            return JsonResponse({'message':'KEY_ERROR'}, status=401)

        except UnboundLocalError :
            return JsonResponse({'message':'이메일/패스워드에 대한 값을 입력해주세요'}, status=401)

        except json.decoder.JSONDecodeError :
            return JsonResponse({'message':'값을 하나라도 입력하세요'})

5. 후기

갈 길이 멀다고 느꼈당

이래서 프로젝트 가능하려나 ;;

좋은 웹페이지 즐겨찾기