본문 바로가기

BackEnd/Python-Flask

[백엔드] Flask: 로그인 API

반응형

로그인 API

 

  • API 명세서:
POST/users/login

email,password

ㄴ POST: 데이터를 저장할 때도 쓰지만, 중요한 데이터를 보낼 때도 사용된다. 

ㄴ email과 password만 있으면 로그인할 수 있다.  


  • email은 유니크 해야하므로, mysql에서 UQ 체크해준다.
  • mysql에서 테이블 설정할 때, password는 암호화 해서, 저장되는 것이기 때문에, varchar의 글자를 길게 설정해야한다. 짧으면 당연히 안된다. 설계 문서대로 하자. 

  • - 로그인 하면, user_id도 필요하다. 클라는 우리 눈에 안보이는 user_id를 서버에게 보내줘야한다.

  • API를 개발할 때는, 먼저 가져오는 데이터가 무엇인지 주석처리로, 적어놓고 한다.
  • 그리고 주석으로 순서 또한 써놓는다. 먼저 로직을 생각해서 코멘트를 달아놓는다. 
  • ㄴ 첫번째 뭐할거고, 두번째는 뭐할거고. 그리고 주석 밑에다가 코드를 하나씩 완성시키면 코드 작성할 때 도움이 많이 된다. 

해당 코드에 사용될 라이브러리

from flask import request
from flask_jwt_extended import get_jwt_identity, jwt_required
from flask_restful import Resource
from mysql.connector.errors import Error
from mysql_connection import get_connection
import mysql.connector
from mysql_connection import get_connection

 

전체 코드는 하기 참고:

더보기
class UserLoginResource(Resource):

    def post (self):

        # 0. postman가서 API를 먼저 만든다.

        # {
        # "email": "gg@gmail.com",
        # "password": "1234"
        # }

        # 1. 클라이언트로부터 body로 넘어온 데이터를 받아온다. (email와 passwords)

        data = request.get_json()

        # 2. email로, DB에 이 이메일과 일치하는 데이터를 가져온다.
        try :
            connection = get_connection()

            query = '''select *
                    from user
                    where email = %s;'''

            record = (data['email'] , )

        # select문은, dictionary = True를 해준다.
            cursor = connection.cursor(dictionary = True)

            cursor.execute(query, record)

            # select문은, 아래 함수를 이용해서, 데이터를 가져온다.
            result_list = cursor.fetchall()
            # 여기에 쿼리의 결과가 있음

            print(result_list)

            # 중요! 디비에서 가져온 timestamp 는
            # 파이썬의 datetime 으로 자동 변경된다.
            # 문제는! 이데이터를 json 으로 바로 보낼수 없으므로,
            # 문자열로 바꿔서 다시 저장해서 보낸다.
            i = 0
            for record in result_list :
                result_list[i]['created_at'] = record['created_at'].isoformat()
                result_list[i]['updated_at'] = record['updated_at'].isoformat()
                i = i + 1              
               
            cursor.close()
            connection.close()

        except mysql.connector.Error as e :
            print(e)
            cursor.close()
            connection.close()

            return {"error" : str(e)}, 503

            # 503으로 보내겠다.

        # result_list정상적일 때는 결과가 리스트의 행이 하나,

        # 3. result_list의 행의 갯수가 1개이면, 유저 데이터를 정상적으로 받아온것이고,
        # 행의 갯수가 0이면, 요청한 이메일은, 회원가입이 되어있지 않은 이메일이다.

        if len(result_list) !=1:
            return{'error': ' 회원가입이 안된 이메일입니다.'}, 400

        # 4. 비밀번호가 맞는지 확인한다.
        user_info = result_list[0]
        # 결과가 리스트니까, 리스트 안에있는 딕셔너리를 가져오겠다는 뜻

        # data['password']와 user_info['password']를 비교
        check = check_password(data['password'],user_info['password'])

        if check == False:
            return {'error':'비밀번호가 맞지 않습니다.'}
           
        # user_id를 바로 보내면 안되고, JWT로 암호화 해서 보내준다.
        # 암호화 하는 방법
        access_token = create_access_token(user_info['id'])
        # 대게는 이런 변수명으로 저장한다.

        return {'result': 'success',
                'access_token':access_token},200

 

반응형