Flask拾遗笔记之Flask-Login插件

Flask-Login的中文文档已经写得很清楚了,这里只做些补充:

必要的部分

  1. 用户类,包含四个属性或方法,方便扩展
is_authenticated: # 是否经过认证了,没什么要求的话,直接返回 Ture
is_active: # 是否可以正常使用,False 的话就代表“封号”了
is_anonymous: # 是否是匿名用户,类似于论坛里面的游客
get_id(): # 返回用的ID标识,为 Flask-Login 获取用户ID提供的一个接口
  1. 加载用户的函数,类似于
@login_manager.user_loader
def load_user(userid):
    pass
# 提供给 Flask-Login 的通过 user 的 ID 获取用户的接口

Flask-Login 的特点

  1. 外部接口由使用者定义。例如加载用户的这个功能,Flask-Login 通过我们给他的函数来加载用户,而不是用 Flask-Login 指定的函数。

  2. 具有 Flask 的特性。①例如,Flask-Login 肯定是线程安全的,因为在它的源码中有如下一段:

     def reload_user(self, user=None):
         ctx = _request_ctx_stack.top
         if user is None:
             # 中间省略
         else:
             ctx.user = user
    

    可以看到 Flask-Login 使用了 _request_ctx_stack, 而这个数据结构在 Flask 内部采用类似于ThreadLocalLocalStack()定义。(什么是 ThreadLocal ?)
    ②再比如 Flask-Login 有current_user代理,代理就是 Flask 中比较有趣的一个概念。Flask-Login 不仅用了LocalStack()还模仿 Flask 对 LocalStack()的操作使用了代理。

  3. 会话保护。Flask-Login 提供的会话保护功能应该是该插件的安全核心所在。(什么是会话保护?)

用户登陆/鉴权

login_manager = Flask-Login.LoginManager()

  1. 通过@login_manager.user_loader
# 通过查询user的id找到请求登录的用户,一般在表单登录时使用
def load_user_by_userid(userid):
    user = User.query_by_user_id(userid)
    return user
  1. 通过 @login_manager.request_loader
# 在request的URL里面获取鉴别用户身份需要的参数,一般在用token鉴权时使用
# request 指 flask.request
def load_user_from_request(request): 
    token = request.args.get('token')
    user = User.query_by_request(token)
    return user
  1. 通过 @login_manager.header_loader
# API接口有时会采用这种方式鉴权
# 这里的 header_val 指的不是 request.headers, 
# 而是 request.headers['Authorization']
@login_manager.header_loader 
def load_user_from_header(header_val):
    user = User.query_by_header(header_val)
    return user

Unicode 问题

在文首的那篇中文文档里面,多次提到的 unicode 概念应该是为了提醒 Python2 的的使用者,因为 Python3 默认编码就是 unicode.

推荐阅读更多精彩内容