如今數據獲取到了,提示也有了,咱們須要把註冊的數據寫入到數據庫,這一步很簡單,直接使用以前提到過的方法,可是咱們不能直接把明文密碼寫入到數據庫中,那樣作是十分不安全的,咱們須要將其加密以後再寫進去,具體是用到werkzeug.security
中的generate_password_hash
這個函數,將字符串變成hash
值。
咱們能夠在User
模型中重寫__init__
函數(或__setattr__
),當傳入password
自動調用generate_password_hash
進行加密,如:html
class Users(db.Model): __tablename__ = 'users_info' id = db.Column(db.Integer, primary_key=True, autoincrement=True) username = db.Column(db.String(32), nullable=False) password = db.Column(db.String(100), nullable=False) register_time = db.Column(db.DateTime, nullable=False, default=datetime.now()) avatar_path = db.Column(db.String(256), nullable=False, default='images/doraemon.jpg') def __init__(self, *args, **kwargs): self.username = kwargs.get('username') self.password = generate_password_hash(kwargs.get('password'))
這樣每添加一個新用戶,在init
的時候就自動把密碼轉爲hash
值了,可是後續咱們還得增長修改密碼的功能,因此就直接簡單點,在收到POST
數據的時候就把密碼加密,而後存入數據庫中,此時註冊的視圖函數代碼以下:數據庫
from flask import Flask, render_template, request, flash, redirect, url_for from models import db, Users from werkzeug.security import generate_password_hash from exts import validate import config ... @app.route('/register/', methods=['GET', 'POST']) def register(): if request.method == 'GET': return render_template('register.html') else: username = request.form.get('username') password1 = request.form.get('password1') password2 = request.form.get('password2') message = validate(username, password1, password2) flash(message) if '成功' in message: new_user = Users(username=username, password=generate_password_hash(password1)) db.session.add(new_user) db.session.commit() return redirect(url_for('login')) else: return render_template('register.html')
這裏獲取登陸或註冊成功的狀態,使用了上一篇文章結尾說的方法,簡化了代碼量。flask
實際上更簡單的方法是,咱們直接對傳入的{{ message }}
進行判斷,若是帶有'成功'
字符串,就顯示藍色,不然就顯示紅色。上文主要是爲了說明@app.context_processor
這個裝飾器,以及session
和g
對象的區別。
那麼一樣的,登陸的驗證過程,就不能直接去拿數據庫加密過的哈希和原始的密碼對比了,咱們用werkzeug.security
的check_password_hash
方法,它能驗證哈希值是否與原始的密碼是匹配的,而後修改validate
函數以下:segmentfault
from models import Users from werkzeug.security import check_password_hash def validate(username, password1, password2=None): user = Users.query.filter(Users.username == username).first() if password2: if user: return '用戶名已經存在' else: if len(username) < 4: return '用戶名長度至少4個字符' elif password1 != password2: return '兩次密碼不一致' elif len(password1) < 6: return '密碼長度至少6個字符' else: return '註冊成功,請登陸' else: if user: if check_password_hash(user.password, password1): return '登陸成功' else: return '密碼錯誤' else: return '用戶名不存在'
登陸頁面的視圖函數以下:安全
@app.route('/login/', methods=['GET', 'POST']) def login(): if request.method == 'GET': return render_template('login.html') else: username = request.form.get('username') password = request.form.get('password') message = validate(username, password) if '成功' in message: return redirect(url_for('home')) else: flash(message) return render_template('login.html')