10.註冊和登陸功能實現(3)—— 註冊數據寫入數據庫

如今數據獲取到了,提示也有了,咱們須要把註冊的數據寫入到數據庫,這一步很簡單,直接使用以前提到過的方法,可是咱們不能直接把明文密碼寫入到數據庫中,那樣作是十分不安全的,咱們須要將其加密以後再寫進去,具體是用到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這個裝飾器,以及 sessiong對象的區別。

那麼一樣的,登陸的驗證過程,就不能直接去拿數據庫加密過的哈希和原始的密碼對比了,咱們用werkzeug.securitycheck_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')
相關文章
相關標籤/搜索