[TIL] 인스타그램 로그인 구현 (views.py)

SEUNGCHAN BAEK·2021년 4월 7일
0

TIL

목록 보기
12/15
post-thumbnail
class LogInView(View):
    def post(self, request):
        data = json.loads(request.body)

        try:
            password = data['password']
            id       = data['id']
            user = ''

            if User.objects.filter(Q(email=id)|Q(phone_number=id)|Q(nickname=id)).exists():
                user = User.objects.get(Q(email=id)|Q(phone_number=id)|Q(nickname=id))
            if not user:
                return JsonResponse({'MESSAGE':'INVALID_USER'}, status=404)



     #두번째 구현 방식


        #     password = data['password']
        #     id = data['id']
        #     user = ''
        #
        #     if User.objects.filter(email=id).exists():
        #         user = User.objects.get(email=id)
        #     if User.objects.filter(nickname=id).exists():
        #         user = User.objects.get(nickname=id)
        #     if User.objects.filter(phone_number=id).exists():
        #         user = User.objects.get(phone_number=id)
        #     if not user:
        #         return JsonResponse({'MESSAGE':'INVALID_USER'}, status=404)

      # 첫번째 구현 방식


            # if 'email' in data:
            #     email = data['email']
            #     if User.objects.filter(email=email).exists():
            #         user = User.objects.get(email=email)
            #     else:
            #         return JsonResponse({'MESSAGE':'INVALID_USER'}, status=401)
            #
            # if 'nickname' in data:
            #     nickname=data['nickname']
            #     if User.objects.filter(nickname=nickname).exists():
            #         user = User.objects.get(nickname=nickname)
            #     else:
            #         return JsonResponse({'MESSAGE':'INVALID_USER'}, status=401)
            #
            # if 'phone_number' in data:
            #     phone_number=data['phone_number']
            #     if User.objects.filter(phone_number=phone_number).exists():
            #         user = User.objects.get(phone_number=phone_number)
            #     else:
            #         return JsonResponse({'MESSAGE':'INVALID_USER'}, status=401)

            encode_password = user.password.encode('utf-8')
            checked_password = bcrypt.checkpw(password.encode('utf-8'), encode_password)

            if not checked_password:
                return JsonResponse({'MESSAGE':'INVALID_PASSWORD'}, status=401)

            access_token = jwt.encode({'id': user.id}, SECRET_KEY, algorithm='HS256')
            return JsonResponse({'MESSAGE':'SUCCESS'}, status=200)

        except KeyError:
            return JsonResponse({'MESSAGE':'KEY_ERROR'}, status=400)
            

인스타그램에서 로그인을 할때 email+password , nickname+password, phone_number+password 방식이 있다.

첫번째로 작성한 코드는 말 그대로 email+password, nickname+password, phone_number+password로 로그인 한다고 생각해서 email로 입력했을때, nickname을 입력했을때, phone_number를 입력했을때를 세가지 변수 각각 경우의 수를 따져서 코드를 구현했다. 작동은 되지만 비효율적인 코드라는것을 깨달았다.

그래서 생각한것이 두번째 방식인데, 생각해보면 사용자가 페이지에서 로그인을 할때 원하는값을 그냥 입력한다. nickname='sdafv', email='asdf@gmail.com', phone_number='010-1234-5689' 이런식으로 나누어서 입력해서 로그인하지 않는다. id 입력칸에 원하는 타입의 id 값을 입력하고 password 칸에 password를 입력한다. 그래서 생각한것이 그냥 어떤 타입으로 입력을하든 id 라는 변수로 받는것이다. id 값으로 입력을 받고 그 id가 데이터베이스의 email or phone_number or nickname에 매칭되는것이 있는지 확인한 후 있으면 유저 정보를 가져오는 방식으로 구현했다. 이렇게 해도 코드는 첫번째 방식보다 훨씬 짧아졌다.

세번째 방식은 Q를 사용한것인데 SQL 문의 where 절과 의미가 비슷하다고 생각하면 된다. Q를 사용하면 여러 if 문으로 구현한 코드가 두번의 if 만으로도 구현이 가능해진다. 가독성이 좋고 간결한 코드로 구현할 수 있다.

그렇게 id가 데이터베이스에 매칭되는것이 있다면 password를 체크하게 되는데 우리가 회원가입을 할때 암호화 시킨 비밀번호를 decode해서 데이터베이스에 저장시켰다. 그래서 로그인 할때 비밀번호가 맞는지 확인하려면 데이터베이스에 decode된 비밀번호를 encode 시킨후에 입력된 비밀번호를 암호화시켜서 서로 똑같은지 비교한다. 비밀번호가 똑같다고 인정되면 'SUCCESS'를 반환한다.

profile
백엔드 개발자가 되는 그날까지

0개의 댓글