SW/Python
[Flask] 로그인 기능
17Hyuk
2022. 5. 3. 01:05
로그인을 구현하기 위해서는 session이 필요하다.
기술적인 부분은 내가 잘 모르기 때문에 다른 블로그를 참조하길 바란다.
기본적으로 template를 사용하므로 파일은 이런식으로 했다.
app.py
from flask import Flask, render_template, request, redirect, session
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField
from wtforms.validators import DataRequired, Length
import app_sql
# StringField : <input type="text">
# PasswordField : <input type="password">
# DataRequired : 유효성검사
app = Flask(__name__)
app.secret_key = "ssijfo@#!@#123" #session을 사용하기 위해서는 반드시 있어야함
class loginform(FlaskForm):
#이 변수명이 input의 name과 id가 되는거임 <input id="user_id" name="user_id" type="text" value="">
#validators=[DataRequired()] : 필수 입력하도록 하는 함수
user_id = StringField('라벨1',validators=[DataRequired(), Length(max=10)])
user_pw = PasswordField('라벨2',validators=[DataRequired(), Length(max=10)])
@app.route('/')
def index():
app_form = loginform() # 클래스를 할당
if 'user_id' in session:
return render_template(
'index.html',
html_form = app_form,
html_login = True,
html_name = session.get('user_id'),
html_title = '로그인성공')
else:
return render_template('index.html',
html_form = app_form,
html_login = False,
html_title = '로그인대기')
#session은 딕셔너리임
#request.args는 GET에서 사용
#request.form은 POST에서 사용
@app.route('/login/', methods=['post'])
def login():
form_id = request.form['user_id']
form_pw = request.form['user_pw']
login_state = app_sql.login(form_id, form_pw) #로그인 실패시 None 성공시 값이 있음
if login_state != None:
session['user_id'] = form_id
return redirect('/')
@app.route('/register/', methods=['post'])
def register():
form_id = request.form['user_id']
form_pw = request.form['user_pw']
app_sql.register(form_id, form_pw)
return redirect('/')
@app.route('/logout/', methods=['post'])
def logout():
session.pop('user_id') # session에서 제거
return redirect('/')
app.run(host='0.0.0.0', port=5000, debug=True)
app_sql.py
import pymysql
#MySQL 접속
mydb = pymysql.connect(
user='tmp',
database='tmpdb',
passwd='1234',
host='localhost',
charset='utf8'
)
#커서생성
sql_cursor = mydb.cursor(pymysql.cursors.DictCursor)
def login(user_id, user_pw):
command = f'''
SELECT * FROM login WHERE userid = '{user_id}' AND userpw = '{user_pw}';
'''
sql_cursor.execute(command)
return sql_cursor.fetchone() # 데이터가 있으며 {'userid': 'A', 'userpw': '1234'}, 없으면 None return
def register(user_id, user_pw):
command = f'''
INSERT INTO login VALUES ('{user_id}', '{user_pw}')
'''
try:
sql_cursor.execute(command) # 중복인 경우 에러 발생하므로 try/except 사용
except:
return print('이미 존재하는 회원')
mydb.commit()
return print('회원가입 완료')
frame.html
<!DOCTYPE html>
<html>
<head>
<title>
{% block title %}
{% endblock %}
</title>
<meta charset="utf-8">
</head>
<body>
<header>
<h1><a href="/">홈</a></h1>
</header>
<nav>
</nav>
<article>
{% block content %}
{% endblock %}
</article>
</body>
</html>
index.html
{% extends 'frame.html' %}
<!--제목-->
{% block title %}
{{html_title}}
{% endblock %}
<!--내용-->
{% block content %}
{% if html_login == True %}
<h2> {{html_name}} 님 반가워요</h2>
<form method="post">
<input type="submit" value="로그아웃" formaction="/logout/">
</form>
{% else %}
<h2>로그인</h2>
<form method="post">
{{ html_form.user_id.label }}
{{ html_form.user_id }}
{{ html_form.user_pw.label }}
{{ html_form.user_pw }}
<input type="submit" value="로그인" formaction="/login/">
<input type="submit" value="회원가입" formaction="/register/">
</form>
{% endif %}
{% endblock %}
설명
validators=[DataRequired(), Length(max=10)]
가 있으므로 아래 사진처럼 값이 없으면 경고창이 뜬다.
그리고 글자수는 최대 10개로 제한된다.
@app.route('/login/', methods=['post'])
def login():
form_id = request.form['user_id']
form_pw = request.form['user_pw']
login_state = app_sql.login(form_id, form_pw) #로그인 실패시 None 성공시 값이 있음
if login_state != None:
session['user_id'] = form_id
return redirect('/')
을 보면 form을 통해서 user_id와 user_pw를 가져오는데
def login(user_id, user_pw):
command = f'''
SELECT * FROM login WHERE userid = '{user_id}' AND userpw = '{user_pw}';
'''
sql_cursor.execute(command)
return sql_cursor.fetchone() # 데이터가 있으며 {'userid': 'A', 'userpw': '1234'}, 없으면 None 이 return됨
그 값을 app_sql.py의 log함수 대응을 해서 성공하면 데이터가 있고 실패하면 None이 return된다.
그후 redirect를 통해서 홈으로 가게 된다.
회원가입도 유사하나
try/except 를 사용해서 id 중복이 나는 경우 오류 발생을 해결해줬다.
@app.route('/')
def index():
app_form = loginform() # 클래스를 할당
if 'user_id' in session:
return render_template(
'index.html',
html_form = app_form,
html_login = True,
html_name = session.get('user_id'),
html_title = '로그인성공')
else:
return render_template('index.html',
html_form = app_form,
html_login = False,
html_title = '로그인대기')
홈으로 가게 되면
로그인을 성공하게 됐으므로 session 딕셔너리에 'user_id'가 존재하게 되므로 if문이 실행된다.
{% if html_login == True %}
<h2> {{html_name}} 님 반가워요</h2>
<form method="post">
<input type="submit" value="로그아웃" formaction="/logout/">
</form>
{% else %}
<h2>로그인</h2>
<form method="post">
{{ html_form.user_id.label }}
{{ html_form.user_id }}
{{ html_form.user_pw.label }}
{{ html_form.user_pw }}
<input type="submit" value="로그인" formaction="/login/">
<input type="submit" value="회원가입" formaction="/register/">
</form>
{% endif %}
이젠 html_login이 True이므로
이런 페이지가 출력된다.