포스트

[Flask] 회원 기능 구현하기 <2 : 회원가입 구현하기>

0. 이전 글

1 : 로그인 구현하기

1. 구현점

  1. 사용자 입력 받기
  2. User 클래스를 통해 적절한 형식인지 검사
  3. 검사가 완료됐으면 관계형 DB에 저장
  4. 관계형 DB를 사용한 로그인 테스트

2. 코드

2.1 DB 연결

1
2
3
4
5
6
7
8
9
10
11
12
13
from flask import request, Blueprint, jsonify
from model.user import User
import pymysql
import config 

db = pymysql.connect(
    host = config.db['host'],
    port = config.db['port'],
    user = config.db['user'],
    passwd = config.db['password'],
    db = config.db['database'],
    charset='utf8'
)

먼저 db와 연결해주어야 한다. pymysql을 사용해 연결했다.

config에는 db의 정보(host, port, user, password…)가 적혀있다. 미리 작성해놓으면 추후 db를 사용할 곳에서 불필요한 코드 작성을 막을 수 있다.

2.2 엔드포인트 설정, register 함수 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
bp_register = Blueprint("sign_up", __name__, url_prefix = "/register")

@bp_register.route('/', methods = ['GET', 'POST'])
def register():
    if request.method == 'POST':
        try:
            cursor = db.cursor()

            data = request.get_json()
            user_id = data.get('user_id')
            email = data.get('email')
            password = data.get('password')

            new_user = User(user_id, password, email) #인스턴스 생성하면서 클래스 내에서 검증함.

            sql = """
            INSERT INTO users(name, email, password)
            VALUES('%s', '%s', '%s')

            """ %(new_user.get_user_id(), new_user.get_user_email(), new_user.get_user_password())

            cursor.execute(sql)
            db.commit()
            return jsonify({"message" : "회원가입 성공"}), 200
        
        except Exception as e:
            print("에러:", e)
            return jsonify({"error": "등록 중 오류가 발생했습니다"}), 500
    else:
        return jsonify({"error": "GET 요청은 불가합니다."}), 500

Blueprint를 사용해 엔드포인트를 지정해주고 회원가입 함수를 만든다.

data = request.get_json() 를 사용해 사용자 입력을 받아주고 user_idpassword에 사용자가 입력한 id와 비밀번호를 할당한다.

그 아래서 따로 작성한 User 클래스를 사용해 적절한 사용자 입력이 들어왔는지 확인한다.

2.3 User 클래스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class User:
    def __init__(self,userid, password, email):
        validate_data(userid, email, password)
        self.user_id = userid
        self.user_pw = password
        self.user_email = email
    
    def get_user_id(self):
        return str(self.user_id)
    
    def get_user_password(self):
        return str(self.user_pw)
    
    def get_user_email(self):
        return str(self.user_email)

def validate_data(userid, email, password):
    if not (userid and email and password):
        raise ValueError("모든 필드는 필수입니다")

여기서는 간단하게 사용자 입력이 있었는지 없었는지 확인하는 검증 함수를 만들었지만, 필요에 따라 아이디와 비밀번호의 조건을 달 수도 있다. (ex. 비밀번호의 길이 등…)

적절한 회원가입 양식이 들어왔다면 아래 쿼리문을 실행하고 “회원가입 성공” 메시지를 로그로 띄워준다.

3. 작동

3.1 회원가입 성공 예

회원가입에 성공하면 로그를 띄워준다.

db에도 적절하게 입력된 것을 볼 수 있다.

(이때 약간의 오류로 비밀번호 필드에 email이 들어갔는데… 테스트니까 그냥 진행했다. 지금은 모두 수정했다.)

3.2 회원가입 실패 예

User클래스 내에서 오류가 발생한 경우

회원가입 시 적절한 양식이 들어오지 않는다면 에러 메시지를 로그로 띄워준다.

이 부분을 세분화한다면 어떤 부분을 충족하지 않았는지도 검증할 수 있다.

GET 요청으로 보낸 경우

회원가입을 POST로 하지 않은 경우에도 해당 오류를 띄워준

4. 로그인 페이지와 함께 테스트

추가적인 회원 정보를 입력 후 이전에 작성했던 로그인 페이지와 비교해보자.

이전에 작성했던 login 함수는 테스트용으로 작성했던 딕셔너리의 회원정보를 가져왔지만, 지금은 관계형 DB에서 가져와야 하기 때문에 코드의 수정이 필요했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def check_userdata(userid, userpw, db):
    row = None
    try:
        if not db.open:
            db.ping(reconnect=True)
        
        sql = """
        SELECT * FROM users WHERE name = %s AND password = %s;  
        """
        cursor = db.cursor()
        cursor.execute(sql, (userid, userpw))

        row = cursor.fetchone()
        print(row)
    
    except Exception as e:
        print("접속오류", e)
    
    finally:
        if db:
            db.close()
        print('종료')

    return row

일단 입력된 아이디와 비밀번호가 db에 있는지 확인하기 위한 함수를 만들었다.

SELECT * FROM users 를 통해 db의 모든 회원 정보를 가져온 후 WHERE 절을 통해 아이디와 비밀번호가 동시에 일치하는 것이 있는지 확인한다.

일치하는 것이 있다면 row에 회원 정보를 할당해 return 하고, 없다면 None을 리턴한다.

1
2
3
4
5
6
userdata = check_userdata(entered_id, entered_pw, db)
        print(userdata)
        if userdata:
            session['username'] = userdata[1]
            session['userpw'] = userdata[3]
            return redirect(url_for('log_in.index'))

그 후 login 함수 내에서 userdata에 row를 리턴하고 True 일 경우 session에 넣어준다.

db에 존재하는 회원정보 중 아무거나 입력해보자.

위 사진처럼 정상적으로 아이디가 입력되면 로그인 성공 후 아이디를 표시해준다.

다음은 아이디는 맞지만 비밀번호가 틀린 경우를 테스트해보자.

로그인되지 않는다.

다음은 아이디와 비밀번호 모두 틀린 경우이다.

역시 되지 않는다.

5. Next

다음은 회원 탈퇴 기능을 구현해 볼 계획이다.



이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.