[Flask] 회원 기능 구현하기 <2 : 회원가입 구현하기>
0. 이전 글
1. 구현점
- 사용자 입력 받기
- User 클래스를 통해 적절한 형식인지 검사
- 검사가 완료됐으면 관계형 DB에 저장
- 관계형 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_id
와 password
에 사용자가 입력한 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
다음은 회원 탈퇴 기능을 구현해 볼 계획이다.