记一次《flask web 开发实战》flask-login学习(不完全的小整理)

前景

先注明,本文章内容还未考证,今天刚碰到,只是学习的人家理论,下面的是出处
https://loli.la/2016/02/11/Flask-Login%E8%AE%B0%E4%BD%8F%E6%88%91/
https://windard.com/blog/2017/10/17/Flask-Session
下面的链接是剖析根源的讲的深一些,上面的还行。由于,web开发实战这本书,上面有些东西讲的不是很清楚,所以自己找寻各种资料并做下记录,之后在实践中去证明。

主要问题

  • flask-login 的流程
  • session,cookie
  • remember_me这个功能

第一步–编写用户类

  • 用户类需要包含四个方法
    用于表示用户的类需要实现这些方法:

    • is_authenticated()
      当用户通过验证时,也即提供有效证明时返回 True 。(只有通过验证的用户 会满足 login_required 的条件。)
    • is_active()
      如果这是一个活动用户且通过验证,账户也已激活,未被停用,也不符合任何你 的应用拒绝一个账号的条件,返回 True 。不活动的账号可能不会登入(当然, 是在没被强制的情况下)。
    • is_anonymous()
      如果是一个匿名用户,返回 True 。(真实用户应返回 False 。)
    • get_id()
      返回一个能唯一识别用户的,并能用于从 user_loader 回调中 加载用户的 unicode 。注意着 必须 是一个 unicode ——如果 ID 原本是 一个 int 或其它类型,你需要把它转换为 unicode 。

要简便地实现用户类,你可以从 UserMixin 继承,它提供了对所有这些方法的默认 实现。(虽然这不是必须的。)


第二步-初始化LonginManager

login_manager = LoginManager()
login_manager.session_protection = 'strong'
login_manager.login_view = 'auth.login'

首先初始化一个对象,然后进行配置

session_protection

session_protection有三种模式:None,basic,strong

  • 用处:保护会话的,防止会话session被盗用,被启用的时候在basic和strong两种模式中运行默认为:basic
  • 读一波源码
    def _session_protection(self):
        sess = session._get_current_object()
        ident = self._session_identifier_generator()

        app = current_app._get_current_object()
        mode = app.config.get('SESSION_PROTECTION', self.session_protection)

        # if the sess is empty, it's an anonymous user or just logged out
        # so we can skip this

        if sess and ident != sess.get('_id', None):
            if mode == 'basic' or sess.permanent:
                sess['_fresh'] = False
                session_protected.send(app)
                return False
            elif mode == 'strong':
                for k in SESSION_KEYS:
                    sess.pop(k, None)

                sess['remember'] = 'clear'
                session_protected.send(app)
                return True

        return False

登录的时候,直接将user_id写入session,session里面有user_id就是登录的,并且标记这个用户是新鲜的,就是通过登录的,而不是用的cookie。
在strong模式下,当之前浏览器关闭的时候,session里面的内容都会删除,只写入一个remember字段为clear,第二次登录时候

app.after_request(self._update_remember_cookie)
def _update_remember_cookie(self, response):
    # Don't modify the session unless there's something to do.
    if 'remember' in session:
        operation = session.pop('remember', None)
        if operation == 'set' and 'user_id' in session:
            self._set_cookie(response)
        elif operation == 'clear':
            self._clear_cookie(response)
    return response

首先session中的remember作为一个单独的cookie写入response,然后传给前端,此时的remember字段由于session中的remember已经被清除,写上了clear,所以清楚了cookie,并传给前端(怎么不清除?改成basic模式,只显示非fresh用户,但是可以继续用cookie)

  • 第一次登录
    记一次《flask web 开发实战》flask-login学习(不完全的小整理)_第1张图片
  • 关闭浏览器之后登录
    记一次《flask web 开发实战》flask-login学习(不完全的小整理)_第2张图片
  • 刷新浏览器之后登录
    记一次《flask web 开发实战》flask-login学习(不完全的小整理)_第3张图片
    PS:图片来自网上,过两天附上自己实验
    对于cookie的过期时间修改等,先留上线索,过两天会用到
    记一次《flask web 开发实战》flask-login学习(不完全的小整理)_第4张图片

login_view

设置登录视图的名称,如果一个未登录用户请求一个只有登录用户才能访问的视图,则闪现一条错误消息默认为

Please log in to access this page

并重定向到这里设置的登录视图。如果未设置登录视图,则直接返回401错误。也可以自己设置错误消息

login_manager.login_message = u"Bonvolu ensaluti por uzi tio paĝo."

第三步,回调函数

@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))

解读:
在每次请求过来后,Flask-Login都会从Session中寻找”user_id”的值,如果找到的话,就会用这个”user_id”值来调用此回调函数就是login_manager 中使用user_loader装饰器设置的callback函数直接获取当前登录的用户,从会话中存储的用户 ID 重新加载用户对象的信息。然后返回到一开始的那个需要登录才能进入的界面。

第四步,登录用户视图函数login()部分

login_user(user, form.remember_me.data)

login_user() 函数的参数是要登录的用户,以及可选的“记住我”布尔值,“记住我”也在表单中填写。如果值为 False ,那么关闭浏览器后用户会话就过期了,所以下次用户访问时要重新登录。如果值为 True ,那么会在用户浏览器中写入一个长期有效的 cookie,使用这个 cookie 可以复现用户会话。

return redirect(request.args.get('next') or url_for('main.index'))

用户访问未授权的 URL 时会显示登录表单,Flask-Login会把原地址保存在查询字符串的 next 参数中,这个参数可从 request.args 字典中读取。如果查询字符串中没有 next 参数,则重定向到首页。

理解:这第一段的话好理解,第二段的意思是当访问需要登录的界面page1时,成功完成登录之后,会设置完cookie,然后返回到之前需要登录才能访问的界面page1,这个地址保存在request.args字典里面,没有的话就回到首页

总结

这次的最大最关键的问题还在cookie和session了,它们的原理,至今还未搞清,尤其是session的部分,之后还需要进一步作为深入。今天只是初步熟悉一下flask-login,过两天要完成登录的界面,并成功完成上述待验证的部分,特做此记录。对于我这样的小白来说,路还很长啊~最好的提升看来还是读源代码加上别人的讲解。

你可能感兴趣的:(flask)