记住我

“记住我”的功能很难实现。但是,Flask-Login 几乎透明地实现它 - 只要把 remember=True 传递给 login_user。一个 cookie 将会存储在用户计算机中,如果用户会话中没有用户 ID 的话,Flask-Login 会自动地从 cookie 中恢复用户 ID。cookie 是防纂改的,因此如果用户纂改过它(比如,使用其它的一些东西来代替用户的 ID),它就会被拒绝,就像不存在。

该层功能是被自动实现的。但你能(且应该,如果你的应用处理任何敏感的数据)提供 额外基础工作来增强你记住的 cookie 的安全性。

可选令牌

使用用户 ID 作为记住的令牌值不一定是安全的。更安全的方法是使用用户名和密码联合的 hash 值,或类似的东西。要添加一个额外的令牌,向你的用户对象添加一个方法:

get_auth_token()

返回用户的认证令牌(返回为 unicode )。这个认证令牌应能唯一识别用户,且不易通过用户的公开信息,如 UID 和名称来猜测出——同样也不应暴露这些信息。

相应地,你应该在 LoginManager 上设置一个 token_loader 函数, 它接受令牌(存储在 cookie 中)作为参数并返回合适的 User 对象。

make_secure_token 函数用于便利创建认证令牌。它会连接所有的参数,然后用应用的密钥来 HMAC 它确保最大的密码学安全。(如果你永久地在数据库中存储用户令牌,那么你会希望向令牌中添加随机数据来阻碍猜测。)

如果你的应用使用密码来验证用户,在认证令牌中包含密码(或你应使用的加盐值的密码 hash )能确保若用户更改密码,他们的旧认证令牌会失效。

”新鲜的“登录(Fresh Logins)

当用户登入,他们的会话被标记成“新鲜的”,就是说在这个会话只中用户实际上登录过。当会话销毁用户使用“记住我”的 cookie 重新登入,会话被标记成“非新鲜的”。login_required 并不在意它们之间的不同,这适用于大部分页面。然而,更改某人 的个人信息这样的敏感操作应需要一个“新鲜的”的登入。(像修改密码这样的操作总是需要 密码,无论是否重登入。)

fresh_login_required,除了验证用户登录,也将确保他们的登录是“新鲜的”。如果不是“新鲜的”,它会把用户送到可以重输入验证条件的页面。你可以定制 fresh_login_required 就像定制 login_required 那样,通过设置 LoginManager.refresh_viewneeds_refresh_message,和 needs_refresh_message_category:

  1. login_manager.refresh_view = "accounts.reauthenticate"
  2. login_manager.needs_refresh_message = (
  3. u"To protect your account, please reauthenticate to access this page."
  4. )
  5. login_manager.needs_refresh_message_category = "info"

或者提供自己的回调来处理“非新鲜的”刷新:

  1. @login_manager.needs_refresh_handler
  2. def refresh():
  3. # do stuff
  4. return a_response

调用 confirm_login 函数可以重新标记会话为”新鲜“。

Cookie 设置

cookie 的细节可以在应用设置中定义。

REMEMBER_COOKIE_NAME存储“记住我”信息的 cookie 名。 默认值: remember_token
REMEMBER_COOKIE_DURATIONcookie 过期时间,为一个 datetime.timedelta 对象。 默认值: 365 天 (1 非闰阳历年)
REMEMBER_COOKIE_DOMAIN如果“记住我” cookie 应跨域,在此处设置域名值 (即 .example.com 会允许 example 下所有子域 名)。 默认值: None
REMEMBER_COOKIE_PATH限制”记住我“ cookie 存储到某一路径下。 默认值: /
REMEMBER_COOKIE_SECURE限制 “Remember Me” cookie 在某些安全通道下有用 (典型地 HTTPS)。默认值: None
REMEMBER_COOKIE_HTTPONLY保护 “Remember Me” cookie 不能通过客户端脚本访问。 默认值: False