一 引言
我们在进行用户的注册时,往往需要将用户输入的明文密码加密成密文进行存储。flask中使用WerkZeug模块可实现这一功能。WerkZeug中有两个方法:
generate_password_hash(password)和check_password_hash(hash,password)。前者用来将明文密码加密,返回加密后的密文,用来进行用户注册。后者将明文和密文进行比较
查看是否一致,用来验证用户登录。
二 模型中增加密文字段
为了讨论WerkZeug的使用,我们先要在User的模型中加入密文字段,并替代之前的密码明文。并引入password属性和验证password的方法。
class User(db.Model):
__tablename__='users'
id=db.Column(db.Integer,primary_key=True)
username=db.Column(db.String(64),unique=True,index=True)
role_id=db.Column(db.Integer,db.ForeignKey('role.id'))
hash_password=db.Column(db.String(28))
def __repr__(self):
return '<User %r>'% self.username
@property
def password(self):
raise AttributeError('password cannot be read');
@password.setter
def password(self,password):
self.hash_password=generate_password_hash(password)
def confirm_password(self,password):
return check_password_hash(self.hash_password,password)
第6行,我们定义了一个hash_password字段,用来保存加密后的密文。
第11~13行,将password字段定义为User类的一个属性,其中设置该属性不可读,若读取抛出AttributeError。
第15~17行,定义password字段的写方法,我们调用generate_password_hash将明文密码password转成密文hash_password。
第19和20行,定义验证密码的函数confirm_password。
三 视图函数中对密码进行加密和验证
重新定义了User模型,接下来我们要在视图函数中定义对用户输入的明文密码进行加密和验证的方法。为了成功验证,在那之前,我们需要先在表单中增加password字段:
from flask_wtf import FlaskForm
from wtforms import TextField,SubmitField,PasswordField
from wtforms.validators import DataRequired
class NameForm(FlaskForm):
name=TextField('what is your name?',validators=[DataRequired()])
password=PasswordField('what is your password?',validators=[DataRequired()])
submit=SubmitField('Submit')
并且,在视图函数返回的html模板中进行相应的处理:
<form method="POST">
{% for message in get_flashed_messages() %}
<p>{{ message }}</p>
{% endfor %}
{{form.hidden_tag()}}
<p>{{form.name.label}}</p>
{{form.name()}}
<p>{{ form.password.label }}</p>
{{ form.password() }}
<br>{{form.submit }}
</form>
我们要实 现的效果是:点击Web上的Submit按钮会新增一个用户,将密码转换成密文密码和用户名一起存入数据库,并且会flash一条'add a user'的信息。此时要求用户在输入一次密码,再次点击Submit按钮,会将验证密码是否正确,并flash对应的信息。视图函数的处理如下:
from datetime import datetime
from flask import flash,render_template,session,redirect,url_for,current_app
from . import main
from .forms import NameForm
from .. import db
from ..models import User
from .. import mail
from ..email import msg
@main.route('/',methods=['GET','POST'])
def index():
form=NameForm()
if form.validate_on_submit():
user=User.query.filter_by(username=form.name.data).first()
if user is None:
user = User(username=form.name.data,password=form.password.data)
db.session.add(user)
flash('add a user')
else:
if user.confirm_password(form.password.data) is True:
flash('password is right')
else:
flash('password is not right')
return render_template('index.html',form=form)
完成上述步骤之后,我们来验证程序的执行。首先,填入用户名和密码,并点击Submit按钮:
我们成功增加了一个用户Jerry,接下来验证密码的正确性。先输入一个错误的密码:
再输入一个正确的密码:
执行结果和我们预期的一致。
Github位置:
https://github.com/HymanLiuTS/flaskTs
克隆本项目:
Git clone git@github.com:HymanLiuTS/flaskTs.git
获取本文源代码:
git checkout FL30