3.用户登录

还记得前面的用户模型吗,里面的password_hash是保存用户密码的哈希值,用于验证用户在登录过程中输入的密码。 实现密码哈希的软件包之一是Werkzeug,你可能在安装Flask时的pip输出中看到过它被提及,因为它是Flask的核心依赖之一。 通过generate_password_hashcheck_password_hash实现密码哈希验证

#app/models.py
from werkzeug.security import generate_password_hash, check_password_hash

# ...

class User(db.Model):
    # ...

    def set_password(self, password):
        self.password_hash = generate_password_hash(password)

    def check_password(self, password):
        return check_password_hash(self.password_hash, password)

现在你可以在flask shell中测试验证下

flask-login

接下来简单介绍下flask-login扩展。该扩展管理用户登录状态,例如用户可以登录应用后,在应用“记住”用户登录时浏览不同页面。它还提供了“记住我”功能,允许用户即使关闭浏览器窗口,也能保持登录状态。

·is_authenticated: 是如果用户拥有有效的凭据或其他条件,该属性是。TrueFalse ·is_active: 属性,即用户账户是否活跃。TrueFalse ·is_anonymous:这是一个面向普通用户的特殊字段,仅限于特殊且匿名的用户。FalseTrue ·get_id(): 一个返回用户唯一标识符字符串的方法。

在应用实例启动后立即创建并初始化后,为Flask-Login准备用户模型

#app/models.py: Flask-Login 用户 mixin 类
# ...
from flask_login import UserMixin

class User(UserMixin, db.Model):
    # ...

此外由于flask-login对数据库一无所知,因此你需要用户加载器功能:

#app/models.py:Flask-Login 用户加载器功能
from app import login
# ...

@login.user_loader
def load_user(id):
    return db.session.get(User, int(id))

登录用户

#app/routes.py:登录视图功能逻辑
# ...
from flask_login import current_user, login_user
import sqlalchemy as sa
from app import db
from app.models import User

# ...

@app.route('/login', methods=['GET', 'POST'])
def login():
    if current_user.is_authenticated:
        return redirect(url_for('index'))
    form = LoginForm()
    if form.validate_on_submit():
        user = db.session.scalar(
            sa.select(User).where(User.username == form.username.data))
        if user is None or not user.check_password(form.password.data):
            flash('Invalid username or password')
            return redirect(url_for('login'))
        login_user(user, remember=form.remember_me.data)
        return redirect(url_for('index'))
    return render_template('login.html', title='Sign In', form=form)

有了登入,还需要登出

#app/routes.py:登出视图功能
# ...
from flask_login import logout_user

# ...

@app.route('/logout')
def logout():
    logout_user()
    return redirect(url_for('index'))

好了,通过前面的网页表单和登录功能,最后的注册功能相信应该不是问题了。

4.个人资料

用户资料页面

#app/routes.py:用户资料视图功能
@app.route('/user/<username>')
@login_required
def user(username):
    user = db.first_or_404(sa.select(User).where(User.username == username))
    posts = [
        {'author': user, 'body': 'Test post #1'},
        {'author': user, 'body': 'Test post #2'}
    ]
    return render_template('user.html', user=user, posts=posts)
#在上述中我创建了假对象,这对于前期开发来说是非常方便的

为了让你的个人资料看起来更加优秀,你还可以添加记录用户最后访问时间,人物简介,头像,个人资料编辑器等功能。