从零开始搭建 flask 博客实验(4)
教程:用户登录模块实战 —— Flask 博客系统(第四篇)
一、项目结构回顾
先看本次教程前后的项目整体结构:
flask
├── app
│ ├── forms.py
│ ├── __init__.py
│ ├── models.py
│ ├── routes.py
│ └── templates
│ ├── base.html
│ ├── index.html
│ └── login.html
├── config.py
├── migrations
│ ├── alembic.ini
│ ├── env.py
│ ├── README
│ ├── script.py.mako
│ └── versions
│ └── …
├── myblog.py
这说明:本次我们将在已有数据库、已有文章模型的基础上,为 用户登录/注册 功能做扩展。 CSDN博客
二、密码加密存储
-
明文存储密码是严重安全问题,因此必须使用加密(哈希)方式存储。 CSDN博客
-
使用 Werkzeug 的
generate_password_hash()与check_password_hash()函数。from werkzeug.security import generate_password_hash, check_password_hash hash = generate_password_hash('mima') check_password_hash(hash, 'mima') # True ``` :contentReference[oaicite:4]{index=4} -
在
User模型中添加两个方法: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) ``` :contentReference[oaicite:5]{index=5} -
测试示例(在 flask shell 中):
u = User(username='duke', email='duke@qq.com') u.set_password('mypwd') db.session.add(u) db.session.commit() u.check_password('mypwd') # True
三、使用 Flask-Login 实现用户会话
(文章中提及了登录与登出视图函数,以及登录限制和注册功能。) CSDN博客
要点如下:
-
在模型中,User 要继承
UserMixin(如果使用 Flask-Login)或手动实现用户验证。 -
在
routes.py中定义:-
登录视图:接收用户名/邮箱 + 密码,检查 user 存在且密码正确,再通过
login_user(user)登录。 -
登出视图:调用
logout_user()。 -
限制访问:在需要登录才能访问的视图上使用
@login_required装饰。
-
-
注册视图:处理新用户注册,调用
User.set_password()存储密码,保存到数据库。 -
前端模板(如
login.html、register.html)要有用户名/邮箱 + 密码字段,并错误提示。
四、完善用户模型与数据库变更
-
在
models.py中为User模型新增字段(如password_hash、last_login、is_active等)以支持登录逻辑。 -
修改模型后,使用迁移命令更新数据库表结构:
flask db migrate -m "add password_hash to User" flask db upgrade -
确保在导入
models时,模型变更被 Flask-Migrate 检测。
五、表单验证与 WTForms (可选)
为用户登录/注册推荐使用 Flask-WTF(WTForms)表单类,在 forms.py 中定义:
class LoginForm(FlaskForm): username = StringField('Username', validators=[DataRequired()]) password = PasswordField('Password', validators=[DataRequired()]) remember_me = BooleanField('Remember Me') class RegistrationForm(FlaskForm): username = StringField('Username', validators=[DataRequired()]) email = StringField('Email', validators=[DataRequired(), Email()]) password = PasswordField('Password', validators=[DataRequired()]) password2 = PasswordField('Repeat Password', validators=[DataRequired(), EqualTo('password')])
然后在视图中使用 form.validate_on_submit() 处理。文章可能没有详述,但这是常见扩展。
六、安全与用户体验建议
-
登录失败应反馈统一提示,避免暴露 “用户名不存在” vs “密码错误” 的区别。
-
注册时应检查用户名/邮箱唯一。
-
密码应设置最小长度、复杂度。
-
登录后可使用
next参数跳转至用户原来想访问的页面。 -
若启用 “记住我”,可设置
login_user(user, remember=True)。
七、总结
通过本篇教程,你的博客系统新增了:
-
安全的用户认证系统(注册/登录/登出)
-
密码的哈希存储机制
-
会话管理机制(通过 Flask-Login)
-
用户模型的完善以及数据库迁移支持
接下来,可以继续扩展:用户资料页、权限管理、文章的“作者”关联、评论管理、后台管理系统等。
