Flask博客項目-用戶登錄(十二)

直到目前,我們的密碼還是以明文的方式存儲在數據庫裏的,這可是個嚴重的安全漏洞!

所以,我們要使用哈希算法的單項加密方法對密碼進行加密

首先,安裝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源碼


其中我在登錄頁面添加了一個隨機生成的驗證碼字段,有興趣的可以下載來看一下

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章