参考:https://blog.csdn.net/weixin_38256474/article/details/81536333 用户登录
https://blog.csdn.net/u014793102/article/details/80399384 用户登录
http://www.pythondoc.com/flask-mega-tutorial/userlogin.html 用户登录
用户模型有一个password_hash
字段,到目前为止尚未使用。它是用于保存用户密码的哈希值,密码用于验证用户在登录过程中输入的密码。密码散列是一个复杂的主题,应交给安全专家,但有几个易于使用的库以一种简单地从应用程序调用的方式实现所有逻辑。
Flask-Login是非常流行Flask扩展。用于管理用户登录状态,以便做到诸如用户可登录到应用程序,然后在应用程序“记住”用户登录并导航到不同页面。它还提供“记住我”功能,即使是在关闭浏览器窗口后,用户也可保持登录状态。在虚拟环境中安装
pip install flask- login
和其他扩展一样,需要在app/__init__.py中的应用程序实例之后立即创建和初始化Flask-Login。app/__init__.py:Flask-Login初始化
为flask-login准备用户模型:flask-login扩展与应用程序的用户模型一起使用,并期望在其中实现某些属性和方法。只要将这些必须的项添加到模型中,flask-login就没有其他要求,因此,例如,它可以与基于任何数据系统的用户模型一起使用
is_authenticated:一个属性,如果用户具有有效凭据则是True,否则是False。
is_active:属性,如果用户的账户处于活动状态则是True;其他状态下是False。
is_anonymous:属性,普通用户则是False;匿名用户则是True。
get_id():一个方法,以字符串形式返回用户的唯一标识符。
我们可轻松地实现上述4个,但由于实现相当通用,Flask-Login提供了一个名为UserMixin的mixin类,它包含适用于大多数用户模型类的通用实现。以下将mixin类添加到模型中:app/models.py:添加Flask-Login用户mixin类
Flask-Login通过在Flask的用户会话中存储其唯一的标识符来跟踪登录用户,这个用户会话是分配给连接到应用程序的每个用户的存储空间。每次登录用户导航到新页面时,Flask-Login都会从会话中检索用户的ID,然后将用户加载到内存中。
因为Flask-Login对数据库一无所知,所以在加载用户时需要应用程序的帮助。因此,扩展期望应用程序配置一个用户加载函数,它可以被调用去加载给定ID的用户。这个函数添加到app/models.py模块中:
使用@user_loader装饰器向flask-login注册用户加载函数,flask-login传递给函数的id作为一个参数将是一个字符串,所以需要将字符串类型转换为int类型工数据库使用数字id
重新访问 登录视图 函数,那时现实了发出flash()
消息的虚假登录。既然应用程序可访问用户数据库,并且知道如何生存、验证密码哈希,那么就可以完成视图功能。
app/routes.py:实现登录视图函数的逻辑
其中,login()函数的前两行处理了一个奇怪情况:想象一下,有一个登录用户,Ta导航到/login
URL。显然这是错误的,不允许这么做。current_user变量来自Flask-Login,可在处理过程中随时使用,以表示请求客户端的用户对象。此变量的值可以是数据库中的用户的对象(Flask-Login通过上述提供的用户加载器回调读取的),如果用户尚未登录,则可以是特殊的匿名用户对象。回想一下用户对象需要Flask-Login的那4个项目(3个属性,1个方法)其中一个是 is_authenticated
,它可以方便地检查用户是否登录。当用户已经登录时,只需重定向到/index
页面。
代替之前的flash()
,现在我们可以将用户登录为真实的。首先,从数据库加载用户。用户名来自于表单提交,filter_by()
方法查询对象。得到的查询结果是只包含具有匹配用户名的对象。因为我们知道1个或0个结果,所以通过调用first()
完成查询,如果存在则返回用户对象,否则返回None
。在第4章,调用all()
将执行查询,得到查询匹配的所有结果的列表。当我们只需要一个结果时,通过使用first()
方法执行查询。
如果我们得到了所提供用户名的匹配项,接下来则可以检查该表单附带的密码是否有效。这将通过调用check_password()
方法完成。它将获取与用户一起存储的密码哈希值,并确定在表单输入的密码是否与哈希值匹配。因此,现在有两个可能的错误条件
用户名可能无效;或用户密码可能不正确。在任一情况下,都将flash一条消息,从重定向到登录页面,以便用户可以再次尝试。
如果用户名、密码都正确,那么将调用来自Flask-Login的login_user()
函数。这个函数将在登录时注册用户,这意味着用户导航的任何未来页面都将current_user
变量设置为该用户。
最后,要完成这个登录过程,只需将新登录的用户重定向到/index
页面。
为用户提供退出应用程序选项,需要使用flask-login的logout_user()函数完成,即退出视图函数:
Flask-Login还提供了一个非常有用的功能:强制用户在查看应用程序的某些页面之前必须登录。如果未登录用户尝试查看受保护的页面,Flask-Login将自动将用户重定向到登录表单,并且仅在登录过程完成后重定向回用户想要查看的页面。
要实现上述功能,Flask-Login需要知道处理登录的视图函数是什么。这可在app/__init__.py中添加:
上述‘login’
的值是登录视图的函数(或端点)名称。也就是:在url_for()
调用中使用的名称来获取URL。
Flask-Login为匿名用户保护视图函数的方式是 使用一个名为@login_required
的装饰器。当将这个装饰器添加到来自Flask的@app.route
的装饰器下方时这个函数将被收到保护,并且不允许未经过身份验证的用户。下方是装饰器如何用于应用程序的index
视图函数:
app/routes.py:添加@login_required装饰器
剩下的是实现:从成功登陆 到 用户想要访问的页面的重定向。当未登录用户访问受@login_required
装饰器保护的视图函数时,装饰器将重定向到登录页面,但它将在此重定向中包含一些额外信息,以便应用程序可返回到第一个页。例如,如果用户到/index
,@login_required
装饰器将拦截请求,并使用重定向响应/login
,但它会向此URL添加一个查询字符串参数,从而形成完成的重定向URL /login?next=/index
。next
查询字符串参数设置为原始URL,因此应用程序可使用这个参数在登录后重定向。
详见:https://blog.csdn.net/weixin_38256474/article/details/81536333
用户注册表单,以便用户通过web表单进行注册,首先在app/forms.py中创建web表单类:
这个与验证相关的新表格中有一些有趣的东西。首先,在email
字段,在添加了DataRequired
验证器后,还添加了第二个验证器Email
。它是WTForms附带的另一个stock validator,它将确保用户在此字段中键入的内容与电子邮件地址的结构相匹配(省了正则去匹配这是否为一个邮箱地址)。
因为这是个注册表单,因此通常都会要求用户输入密码两次以减少拼写错误的风险。因此,用了password、password2
两个字段。第二个字段 用了另一个stock validator EqualTo
,它将确保其值与第一个密码字段的值相同。
还为这个类添加两个方法:validate_username()
、validate_email()
。当添加与模式匹配任何 validate_字段名
方法时,WTForms会将这些方法作为自定义验证器,并在stock validator 之外调用它们。在这种情况下,确定用户输入的用户名、电子邮件地址是否在数据库中,因此这俩个方法会发出数据库查询。如果存在查询结果,则通过触发验证错误ValidationError
。将在字段傍边显示包含此异常的消息让用户查看。
要在网页上显示这个Web表单,还需一个HTML模板,存于app/templates/register.html中,此模板的构造类似于登录表单的模板:
首先,确定调用此路由的用户未登录。表单的处理方式与登录的相同。在if validate_on_submit()
判断内完成以下逻辑:创建一个新用户,其中提供用户名、电子邮件地址、密码,将其写入数据库,最后重定向到登录页面,以便用户登录。