ํ๋ผ์คํฌ (Flask) - ํ์๊ฐ์ ๊ธฐ๋ฅ ๋ง๋ค๊ธฐ 2 (flask - WTF ์ด์ฉํ๊ธฐ)
- -
*Flask - WTF
- ์ค์น pip install flask-WTF
- flask์ form์ ๊ด๋ฆฌํ ์ ์๋ ๊ธฐ๋ฅ ์ ๊ณต.
- CSRF( Cross-site request forgery) protect
- ์ ํจ์ฑ ๊ฒ์ฆ(validation)
1. csrf protect
from flask_wtf.csrf import CSRFprotect
if __name__ == "__main__":
app.config['SECRET_KEY'] = 'wcsfeufhwiquehfdx'
csrf = CSRFProtect()
csrf.init_app(app)
์ํฌ๋ฆฟ ํค๋ฅผ ์ค์ ํด์ฃผ๊ณ , (์์๋ ์์๋ก ์ค์ ํ์ต๋๋ค.) csrf ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ app์ํตํด ์ด๊ธฐํํ๋ฉด ๋ฉ๋๋ค.
2. form, Validators, StringField, PasswordField
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField
from wtforms.validators import DataRequired, EqualTo
class RegisterForm(FlaskForm):
userid = StringField('userid', validators=[DataRequired()])
username = StringField('username', validators=[DataRequired()])
password = PasswordField('password', validators=[DataRequired(), EqualTo('re_password')]) #equalTo("ํ๋๋ค์")
re_password = PasswordField('re_password', validators=[DataRequired()])
FlaskForm : ํผ์ ์์ฑํฉ๋๋ค. html์์๋ from์ ํตํด ์์ฑํ ์ ์์ต๋๋ค.
StringField, PasswordField : ๋ฌธ์ ๊ทธ๋๋ก์ ๋๋ค. ์ด๋ ํ ํ์์ผ๋ก ์๋ฃ๋ฅผ ๋ค๋ฃฐ์ง ์ค์ ํฉ๋๋ค. PasswordField๋ก ์ค์ ํ๋ฉด *********์ ๊ฐ์ ํ์์ผ๋ก ์ธ๋ถ์๋ ๋ฌธ์๊ฐ ๋ณด์ด์ง ์์ต๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก ๋ค์ด๊ฐ๋ฉด ์ผ๋ฐ์ ์ธ ๋ฌธ์๋ก ํ์ธ ๊ฐ๋ฅํฉ๋๋ค.
EqualTo : password ์ re_password๊ฐ ์ผ์นํ๋์ง ํ์ธ ํฉ๋๋ค. ์ด์ ํฌ์คํ ์์๋ if password==re_password : ์ ๊ฐ์ด ์ง์ ์กฐ๊ฑด๋ฌธ์ ํตํด ๊ฒ์ฆํ์ง๋ง EqualTo๋ฅผ ์ฌ์ฉํ๋ฉด ์กฐ๊ฑด๋ฌธ์ด ํ์ ์์ด์ง๋๋ค.
DataRequired : ๊ณต๋ฐฑ์ผ๋ก ์ ๋ ฅ๋์ง ์์๋์ง, ๋ฐ์ดํฐ๊ฐ ์ ๋ ฅ๋์๋์ง ํ์ธํฉ๋๋ค. ๋ง์ฝ ๋ฐ์ดํฐ๊ฐ ์ ๋ ฅ๋์ง ์์์ฑ๋ก POST๋๋ค๋ฉด ๋ฐ์ ๊ทธ๋ฆผ์ฒ๋ผ "์ด ์ ๋ ฅ๋์ ์์ฑํ์ธ์."๋ผ๊ณ ๋ฉ์์ง๊ฐ ๋น๋๋ค.
*๊ตฌ์กฐ (Structure)
Flaskํด๋
โ โโโ templates (ํด๋)
โ โโโ register.html
โ
โ
โโโ app.py (์คํํ์ผ)
โโโ db.sqlite (์ด๊ฑด ์๋์ผ๋ก ์์ฑ๋จ)
โโโ models.py
โโโ forms.py
*models.py
##๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๊ด๋ จ๋ ์ฝ๋
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy() #SQLAlchemy๋ฅผ ์ฌ์ฉํด ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ์ฅ
class Fcuser(db.Model):
__tablename__ = 'fcuser' #ํ
์ด๋ธ ์ด๋ฆ : fcuser
id = db.Column(db.Integer, primary_key = True) #id๋ฅผ ํ๋ผ์ด๋จธ๋ฆฌํค๋ก ์ค์
password = db.Column(db.String(64)) #ํจ์ค์๋๋ฅผ ๋ฐ์์ฌ ๋ฌธ์์ด๊ธธ์ด
userid = db.Column(db.String(32)) #์ดํ ์์ ๋์ผ
username = db.Column(db.String(8))
*app.py
import os #์ ๋๊ฒฝ๋ก๋ฅผ ์ง์ ํ๊ธฐ ์ํ Os๋ชจ๋ ์ํฌํธ
from flask import Flask
from flask import request #ํ์์ ๋ณด ์ ์ถํ์๋ ๋ฐ์์ค๊ธฐ ์ํ request, post์์ฒญ์ ํ์ฑํ์ํค๊ธฐ ์ํจ
from flask import redirect #ํ์ด์ง ์ด๋์ํค๋ ํจ์
from flask import render_template
from models import db
from models import Fcuser #๋ชจ๋ธ์ ํด๋์ค ๊ฐ์ ธ์ค๊ธฐ.
from flask_wtf.csrf import CSRFProtect
from forms import RegisterForm
app = Flask(__name__)
@app.route('/register', methods=['GET','POST']) #๊ฒ, ํฌ์คํธ ๋ฉ์๋ ๋๋ค ์ฌ์ฉ
def register(): #get ์์ฒญ ๋จ์ํ ํ์ด์ง ํ์ post์์ฒญ ํ์๊ฐ์
-๋ฑ๋ก์ ๋๋ ์๋ ์ ๋ณด ๊ฐ์ ธ์ค๋๊ฒ
form = RegisterForm()
if form.validate_on_submit(): # POST๊ฒ์ฌ์ ์ ํจ์ฑ๊ฒ์ฌ๊ฐ ์ ์์ ์ผ๋ก ๋์๋์ง ํ์ธํ ์ ์๋ค. ์
๋ ฅ ์ํ๊ฒ๋ค์ด ์๋์ง ํ์ธ๋จ.
#๋น๋ฐ๋ฒํธ = ๋น๋ฐ๋ฒํธ ํ์ธ -> EqulaTo
fcuser = Fcuser() #models.py์ ์๋ Fcuser
fcuser.userid = form.data.get('userid')
fcuser.username = form.data.get('username')
fcuser.password = form.data.get('password')
print(fcuser.userid,fcuser.password) #ํ์๊ฐ์
์์ฒญ์ ์ฝ์์ฐฝ์ ID๋ง ์ถ๋ ฅ (ํ์ธ์ฉ, ๋ฑํ ํ์์์)
db.session.add(fcuser) # id, name ๋ณ์์ ๋ฃ์ ํ์์ ๋ณด DB์ ์ ์ฅ
db.session.commit() #์ปค๋ฐ
return "๊ฐ์
์๋ฃ" #post์์ฒญ์ผ์๋ '/'์ฃผ์๋ก ์ด๋. (ํ์๊ฐ์
์๋ฃ์ ํ๋ฉด์ด๋)
return render_template('register.html', form=form)
@app.route('/')
def hello():
return render_template('hello.html') # ์ด๋ฒ ํฌ์คํ
์๋ ํ์์์(์ง๋ํฌ์คํ
๊บผ)
if __name__ == "__main__":
basedir = os.path.abspath(os.path.dirname(__file__)) #dbํ์ผ์ ์ ๋๊ฒฝ๋ก๋ก ์์ฑ
dbfile = os.path.join(basedir, 'db.sqlite')#dbํ์ผ์ ์ ๋๊ฒฝ๋ก๋ก ์์ฑ
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + dbfile
#sqlite๋ฅผ ์ฌ์ฉํจ. (๋ง์ฝ mysql์ ์ฌ์ฉํ๋ค๋ฉด, id password ๋ฑ... ๋ ํ์ํ๊ฒ๋ง๋ค.)
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
#์ฌ์ฉ์ ์์ฒญ์ ๋๋ง๋ค ์ปค๋ฐ(๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ,์์ ,์ญ์ ๋ฑ์ ๋์์ ์์๋จ๋ ๊ฒ๋ค์ ์คํ๋ช
๋ น)์ ํ๋ค.
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
#์์ ์ฌํญ์ ๋ํ track์ ํ์ง ์๋๋ค. True๋ก ํ๋ค๋ฉด warning ๋ฉ์์ง์ ๋ฐ
app.config['SECRET_KEY'] = 'wcsfeufhwiquehfdx'
csrf = CSRFProtect()
csrf.init_app(app)
db.init_app(app)
db.app = app
db.create_all() #db ์์ฑ
app.run(host='127.0.0.1', port=5000, debug=True)
#ํฌํธ๋ฒํธ๋ ๊ธฐ๋ณธ 5000, ๊ฐ๋ฐ๋จ๊ณ์์๋ debug๋ True
*forms.py
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField
from wtforms.validators import DataRequired, EqualTo
class RegisterForm(FlaskForm):
userid = StringField('userid', validators=[DataRequired()])
username = StringField('username', validators=[DataRequired()])
password = PasswordField('password', validators=[DataRequired(), EqualTo('re_password')]) #equalTo("ํ๋๋ค์")
re_password = PasswordField('re_password', validators=[DataRequired()])
*register.html
<html>
<head>
<meta charset='utf-8'/>
<meta name='viewport' content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous">
</script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous">
</script>
</head>
<body>
<div class="container">
<div class="row mt-5">
<h1>ํ์๊ฐ์
</h1>
</div>
<div class="row mt-5">
<div class="col-12">
<form method="POST" > <!--์์
์ญ์ ํด์ผ๋-->
{{form.csrf_token}}
<div class="form-group">
<!-- <label for="userid">์์ด๋</label>
<input type="text" class="form-control" id="userid" placeholder="์์ด๋" name="userid" /> -->
{{form.userid.label("์์ด๋")}}
{{form.userid(class="form-control", placeholder="์์ด๋")}}
</div>
<div class="form-group">
<!-- <label for="username">์ด๋ฆ</label>
<input type="text" class="form-control" id="username" placeholder="์ฌ์ฉ์์ด๋ฆ" name="username" /> -->
{{form.username.label("์ฌ์ฉ์ ์ด๋ฆ")}}
{{form.username(class="form-control", placeholder="์ฌ์ฉ์ ์ด๋ฆ")}}
</div>
<div class="form-group">
<!-- <label for="password">๋น๋ฐ๋ฒํธ</label>
<input type="password" class="form-control" id="password" placeholder="๋น๋ฐ๋ฒํธ" name="password" /> -->
{{form.password.label("๋น๋ฐ๋ฒํธ")}}
{{form.password(class="form-control", placeholder="๋น๋ฐ๋ฒํธ")}}
</div>
<div class="form-group">
<!-- <label for="re-password">๋น๋ฐ๋ฒํธ ํ์ธ</label>
<input type="password" class="form-control" id="re_password" placeholder="๋น๋ฐ๋ฒํธ ํ์ธ" name="re-password" /> -->
{{form.re_password.label("๋น๋ฐ๋ฒํธ ํ์ธ")}}
{{form.re_password(class="form-control", placeholder="๋น๋ฐ๋ฒํธ ํ์ธ")}}
</div>
<button type="submit" class="btn btn-primary">์ ์ถ</button>
</form>
</div>
</div>
</div>
</body>
</html>
์ง๋ ํฌ์คํ ๊ณผ ๊ฒฐ๊ณผ๋ฌผ์ ๊ธฐ๋ฅ๊ณผ ๋ชจ์์ ๊ฐ์ต๋๋ค. ํ์ง๋ง ์ด๋ ๊ฒ WTF๋ฅผ ์ฌ์ฉํ์ฌ ๋ ์ฝ๋๊ฐ ๊ฐ๊ฒฐํด์ก๊ณ , csrf_protect ๊ธฐ๋ฅ๋ ์๊ฒผ์ต๋๋ค.
์ง๋ํฌ์คํ : https://infinitt.tistory.com/30
'๐ ํ์ด์ฌ (Python)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
ํ๋ผ์คํฌ (Flask) Static ํ์ผ ์ ์ฉํ๊ธฐ. (CSS, JS) url_for (0) | 2020.02.07 |
---|---|
ํ์ด์ฌ (python) ๋ฆฌ์คํธ๊ฐ ๋น์ด์๋์ง ํ์ธ, ๋น ๋ฐฐ์ด ํ์ธํ๊ธฐ (2) | 2020.02.06 |
ํ์ด์ฌ (Python) 2์ค ๋ฆฌ์คํธ, 2์ฐจ์ ๋ฐฐ์ด ์ ์ธ ๋ฐ ์ถ๋ ฅ (7) | 2020.02.02 |
ํ์ด์ฌ(python) ์ผํญ ์ฐ์ฐ์ (if , else) (0) | 2020.02.01 |
ํ์ด์ฌ(python) ๋นํธ ์ฐ์ฐ์ (bitwise Operator) (0) | 2020.02.01 |
๋น์ ์ด ์ข์ํ ๋งํ ์ฝํ ์ธ
-
ํ๋ผ์คํฌ (Flask) Static ํ์ผ ์ ์ฉํ๊ธฐ. (CSS, JS) url_for 2020.02.07
-
ํ์ด์ฌ (python) ๋ฆฌ์คํธ๊ฐ ๋น์ด์๋์ง ํ์ธ, ๋น ๋ฐฐ์ด ํ์ธํ๊ธฐ 2020.02.06
-
ํ์ด์ฌ (Python) 2์ค ๋ฆฌ์คํธ, 2์ฐจ์ ๋ฐฐ์ด ์ ์ธ ๋ฐ ์ถ๋ ฅ 2020.02.02
-
ํ์ด์ฌ(python) ์ผํญ ์ฐ์ฐ์ (if , else) 2020.02.01
์์คํ ๊ณต๊ฐ ๊ฐ์ฌํฉ๋๋ค