从零开始搭建 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博客

要点如下:

  1. 在模型中,User 要继承 UserMixin(如果使用 Flask-Login)或手动实现用户验证。

  2. routes.py 中定义:

    • 登录视图:接收用户名/邮箱 + 密码,检查 user 存在且密码正确,再通过 login_user(user) 登录。

    • 登出视图:调用 logout_user()

    • 限制访问:在需要登录才能访问的视图上使用 @login_required 装饰。

  3. 注册视图:处理新用户注册,调用 User.set_password() 存储密码,保存到数据库。

  4. 前端模板(如 login.htmlregister.html)要有用户名/邮箱 + 密码字段,并错误提示。

四、完善用户模型与数据库变更

  • models.py 中为 User 模型新增字段(如 password_hashlast_loginis_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)

  • 用户模型的完善以及数据库迁移支持

接下来,可以继续扩展:用户资料页、权限管理、文章的"作者"关联、评论管理、后台管理系统等。

相关推荐
vyuvyucd2 分钟前
MPPI算法实战:机器人避障与仿真
python
计算机徐师兄3 分钟前
Python基于Flask的广东旅游数据分析系统(附源码,文档说明)
python·flask·旅游数据分析·广东旅游数据分析系统·python广东数据分析系统·python广东旅游数据分析·python旅游数据分析系统
jarreyer5 分钟前
数据项目分析标准化流程
开发语言·python·机器学习
GZKPeng7 分钟前
pytorch +cuda成功安装后, torch.cuda.is_available 是False
人工智能·pytorch·python
我的xiaodoujiao8 分钟前
使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 39--生成 Allure测试报告
python·学习·测试工具·pytest
Coder_Boy_9 分钟前
Spring Boot 事务回滚异常 UnexpectedRollbackException 详解(常见问题集合)
java·spring boot·后端
风象南10 分钟前
SpringBoot 实现网络限速
后端
陈小桔12 分钟前
logging模块-python
开发语言·python
源代码•宸15 分钟前
Golang语法进阶(定时器)
开发语言·经验分享·后端·算法·golang·timer·ticker
水中加点糖16 分钟前
RagFlow实现多模态搜索(文、图、视频)与(关键字/相似度)搜索原理(二)
python·ai·音视频·knn·ragflow·多模态搜索·相似度搜索