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

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

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

相关推荐
bcbnb2 小时前
iPhone HTTPS 抓包,从无法抓包到定位问题的流程(Charles/tcpdump/Wireshark/Sniffmaster)
后端
Data_Adventure2 小时前
TypeScript 开发者转向 Java:学习重点与思维迁移指南
后端
吴祖贤2 小时前
Spring AI 零基础入门:从踩坑到上手的完整指南
后端
code_std3 小时前
SpringBoot 登录验证码
java·spring boot·后端
Mos_x3 小时前
@RestController注解
java·后端
咋吃都不胖lyh3 小时前
比较两个excel文件的指定列是否一致
爬虫·python·pandas
bcbnb3 小时前
Fiddler抓包工具使用教程,HTTPHTTPS抓包、代理配置与调试技巧全解析(附实战经验)
后端
虎子_layor3 小时前
PostgreSQL这么多优势,为什么还要使用MySQL
后端·sql