直到目前,我們的密碼還是以明文的方式存儲在數據庫裏的,這可是個嚴重的安全漏洞!
所以,我們要使用哈希算法的單項加密方法對密碼進行加密
首先,安裝lFlask Bcrypt包:
pip insta flask_bcrypt
這裏需要用app進行初始化的拓展(像SQLAlchemy對象一樣)
我們在一個不顯而易見的地方進行我們的拓展,放在__init__.py同級目錄下,命名爲extensions.py
from flask_bcrypt import Bcrypt
bcrypt = Bcrypt()
接着在__init__.py中進行初始化:
from webapp.extensions import bcrypt
def create_app(object_name):
...
db.init_app(app)
bcrypt.init_app(app)
...
return app
然後是在model.py中對密碼進行hash加密:
from webapp.extensions import bcrypt
...
class User(db.Model):
...
def set_password(self, password):
self.password = bcrypt.generate_password_hash(password)
def check_password(self, password):
return bcrypt.check_password_hash(self.password, password)
其中,set_password()函數用於:對密碼進行加密
check_password()函數用於:對加密後的密碼進行解密
最後是在登錄流程中,使用到上述的方法來創建新用戶並檢查密碼:
(這裏我們要補充一下我們的表單頁面
因爲我們先前只創建了一個提交評論的表單,這是不夠的)
from webapp.models import User
class LoginForm(FlaskForm):
username = StringField('Username', validators=[DataRequired(), Length(max=255)])
password = PasswordField('Password', [DataRequired()])
def validate(self):
check_validate = super().validate()
if not check_validate:
return False
user = User.qury.filter_by(username=self.username.data).first()
if not user:
self.username.errors.append('Invalid username')
return False
return True
class PostForm(Form):
title = StringField('Title', [DataRequired(), Length(max=255)])
text = TextAreaField('Content', [DataRequired()])
然後是在(引用這些表單的路由)main.py裏:
@main_blueprint.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first_or_404()
if session.get('image').lower() != form.captcha.data.lower():
flash('Wrong Captcha code.')
return render_template('login.html', form=form)
if form.validate():
login_user(user, form.remember.data)
return redirect(request.args.get('next') or url_for('main.index'))
# flash('Invalid username or password.')
return render_template('login.html', form=form)
@main_blueprint.route('/logout', methods=['GET', 'POST'])
def logout():
from flask_login import logout_user
logout_user()
flash('You have been logged out', category='success')
return render_template('main.home')
其中我們用到了session,我們將變量保存在了會話中以方便我們在請求的過程中使用到
並且在__init__.py中插入flask_login來控制用戶登錄/註銷狀態
flask_login的安裝:
pip install flask-login
from flask_login import LoginManager
#flask_login配置
login_manager = LoginManager()
login_manager.session_protection = 'strong'
login_manager.login_view = 'main.login'
def create_app(object_name):
...
login_manager.init_app(app)
...
其中,flask_login需要在app中進行初始化
隨後是html的處理,篇幅太大,這就不做過多介紹,下面是源碼:
點擊此處查看Git源碼
其中我在登錄頁面添加了一個隨機生成的驗證碼字段,有興趣的可以下載來看一下