flask-用户认证(上)

本文详细介绍了如何使用Flask、Werkzeug和Flask-Login实现用户认证功能。内容涵盖Werkzeug的密码散列,创建认证蓝本,使用Flask-Login管理用户登录状态,包括用户登录、登出、登录表单、测试登录流程,以及注册新用户的表单验证和数据库操作。同时,强调了安全性和模板组织结构的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要用到的包:

  • Flask-Login: 管理已登录用户的用户会话。
  • Werkzeug: 计算密码散列值并进行核对(把密码变成散列值
  • itsdangerous: 生成并核对加密安全令牌(确认邮件)。

Werkzeug实现密码散列

若想保证数据库中用户密码的安全,要存储密码的散列值。计算密码散列值的函数接收密码作为输入,使用一种或多种加密算法转换密码,最终得到一个和原始密码没有关系的字符序列。核对密码时,密码散列值可代替原始密码,因为计算散列值的函数是可复现的:只要输入一样,结果就一样。

Werkzeug 中的 security 模块能很方便地实现密码散列值的计算。只需要两个函数,分别用在注册和验证用户阶段。

  • generate_password_hash(password, method=pbkdf2:sha1, salt_length=8):这个函数将原始 密码作为输入,以字符串形式输出密码的散列值, 输出的值可保存在用户数据库中。method 和 salt_length 的默认值就能满足大多数需求。
  • check_password_hash(hash, password):这个函数的参数是从数据库中取回的密码散列值和用 户输入的密码。返回值为 True 表明密码正确。

在 User 模型中加入密码散列:

from werkzeug.security import generate_password_hash, check_password_hash

class User(db.Model):
    password_hash = db.Column(db.String(128))
    
    @property   #私有
    def password(self):
        raise AttributeError('password is not a readable attribute')
    
    @password.setter  #只可写不可读  
    def password(self, password):
      self.password_hash = generate_password_hash(password)
    
     def verify_password(self, password):
        return check_password_hash(self.password_hash, password)

计算密码散列值的函数通过名为 password 的只写属性实现。设定这个属性的值时,赋值方法会调用Werkzeug 提供的generate_password_hash()函数,并把得到的结果赋值给password_hash 字段。如果试图读取 password 属性的值,则会返回错误,原因很明显,因为生成散列值后就无法还原成原 来的密码了。

verify_password 方法会把传入的密码和存储在 User 模型中的密码散列值进行比对。如果这个方法返回 True,就表明密码是正确的。

创建认证蓝本

把创建程序的过程移入工厂函数后,可以使用蓝本在全局作用域中定义路由。 对于不同的程序功能,使用不同的蓝本。

auth 蓝本的包构造文件创建蓝本对象,再从 views.py 模块中引入 路由。

【app/auth/init.py: 创建蓝本

from flask import Blueprint
auth = Blueprint('auth',__name__)
from . import views

app/auth/views.py 模块引入蓝本,然后使用route 修饰器定义与认证的 /login/路由。渲染同名占位模板。

【app/templates/auth/login.html】

{% extends "base.html" %}
{% block title %}Flasky - Login{% endblock %}
{% block page_content %}
<div class="page-header">
    <h1>Login</h1>
</div>
{% endblock %}

【app/auth/views.py: 蓝本中的路由和视图函数】

from flask import render_template
from . import auth
@auth.route('/login/')

def login():
    return render_template('auth/login.html')

注意:

为 render_template() 指定的模板文件保存在 auth 文件夹中。这个文件夹必须在 app/templates 中创建, Flask 认为模板的路径是相对于程序模板文件夹而言的。为了避免与 main 蓝本和后续添加的蓝本发生模板命名冲突,可以把蓝本使用的模板保存在单独的文件夹中。

auth 蓝本要在 app/init.py的create_app() 工厂函数中附加到程序上

【app/init.py: 附加蓝本】

def create_app(config_name):
   
    from .auth import auth 
    app.register_blueprint(auth,url_prefix='/auth')
   
    return app

url_prefix 是可选参数,使用后,注册后蓝本中定义的所有路由都会加上指定的前缀。例如:/login路由会注册成/auth/login, 在开发 Web 服务器中,完整的 URL 就变成了 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值