플라스크가 마이크로 프레임워크이므로 기능들이 부족하다. 그래서 form관리를 할 때 쓰는 패키지가 WTF이다.
파이썬에서 form을 만들고 template에 전달에서 form을 표현할 것이다. 이렇게 하면 csrf보호기법, validation을 편하게 할 수 있다.
CSRF는 사이트 간 요청 위조를 방지하기 위해서 form안에 암호화된 해쉬키를 넣어놓고 직접 만든 사이트안에서 일어나는 요청인지 아닌지 판별하는 패키지이다.
CSRF 해쉬값을 자동으로 전달해서 검증해준다.
1. form.py
form을 관리하는 파일을 따로 만든다.
from flask_wtf import FlaskForm
from wtforms import StringField
from wtforms import 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('repassword')])
# EqualTo는 비밀번호 확인과 같은지 검사한다.
repassword = PasswordField('repassword', validators=[DataRequired()])
생성한 form객체가 정보를 받을 때 유효성 검사까지 알아서 해준다.
2. register.html
기존의 form 부분을 보면 이런식으로 되어있다.
...
<form method="POST">
<div class="form-group">
<label for="userid">아이디</label>
<input type="text" class="form-control" id="userid" placeholder="아이디" name="userid" />
</div>
<div class="form-group">
<label for="username">사용자 이름</label>
<input type="text" class="form-control" id="username" placeholder="사용자 이름" name="username" />
</div>
<div class="form-group">
<label for="password">비밀번호</label>
<input type="password" class="form-control" id="password" placeholder="비밀번호" name="password" />
</div>
<div class="form-group">
<label for="re-password">비밀번호 확인</label>
<input type="password" class="form-control" id="re-password" placeholder="비밀번호 확인" name="re-password" />
</div>
<button type="submit" class="btn btn-primary">등록</button>
</form>
...
이것을 생성한 wtf를 이용한 form 객체 형식에 맞춰 바꾸고, csrf를 추가한다.
...
<form method="POST">
{{form.csrf_token}}
<div class="form-group">
{{form.userid.label("아이디")}}
{{form.userid(class="form-control", placeholder="아이디")}}
</div>
<div class="form-group">
{{form.username.label("사용자 이름")}}
{{form.username(class="form-control", placeholder="사용자이름")}}
</div>
<div class="form-group">
{{form.password.label("비밀번호")}}
{{form.password(class="form-control", placeholder="비밀번호")}}
</div>
<div class="form-group">
{{form.repassword.label("비밀번호 확인")}}
{{form.repassword(class="form-control", placeholder="비밀번호 확인")}}
</div>
<button type="submit" class="btn btn-primary">등록</button>
</form>
...
함수처럼 사용하면돼서 훨씬 간단하고 직관적이다. {{form.csrf_token}} 이것은 csrf를 활성화하는 것이다.
csrf_token을 통해서 value로 저런 해시값이 들어오고 이것을 통해 사이트 간 요청위조를 판별한다.
3. app.py
이제 control부분을 수정한다. form객체에서 POST 메소드 여부와 유효성을 자동으로 검사하므로 훨씬 간단하게 작성할 수 있다.
...
from forms import RegisterForm
...
@app.route('/register', methods=['GET', 'POST'])
def register():
form = RegisterForm()
if form.validate_on_submit():
fcuser = Fcuser()
fcuser.userid = form.data.get('userid')
fcuser.username = form.data.get('username')
fcuser.password = form.data.get('password')
db.session.add(fcuser)
db.session.commit()
print('Success!')
return redirect('/')
return render_template('register.html', form=form)
...
validate_on_submit()함수가 POST요청여부와 요청에 담긴 데이터의 유효성을 자동으로 검사해준다. 그리고 form이 어떤 form인지 form=form으로 명시해준다.
그리고 csrf를 사용하기 위해서 app을 설정해줘야한다.
...
if __name__ == "main":
...
app.config['SECRET_KEY'] = 'aksldjfalksdj' # 해시값은 아무거나 적었다.
csrf = CSRFProtect()
csrf.init_app(app)
...
이제 저 해시값을 기준으로 암호화하여 검사한다.
'PNU DSC > Solution Challenge' 카테고리의 다른 글
Flask 11. 로그인 페이지 만들기 (0) | 2020.03.10 |
---|---|
Flask 10. static 파일 관리하기 (0) | 2020.03.10 |
Flask 08. 회원관리 - Controller (0) | 2020.03.09 |
Flask 07. 회원관리 - View (bootstrap) (0) | 2020.03.09 |
Flask 06. 회원가입 - Model (0) | 2020.03.09 |