使用flask-login确保每个帐户的单个用户

时间:2015-04-03 03:10:00

标签: python cookies flask flask-login

我理解Flask-login的方式是,一旦经过身份验证,它会设置一个包含随每个请求一起发送的用户ID的cookie,以便服务器可以将请求与(已登录)用户相关联。用户ID几乎被编码为用户ID和一些浏览器设置(我认为是用户代理)的函数。

由此产生了一些问题,也许有人可以对它们发表评论并建议解决方案。

  • 客户可以通过猜测用户ID并使用相同的cookie编码功能来假装成为登录用户来请求内容。
  • 多个用户在共享帐户凭据时可以使用两台不同计算机上的相同用户帐户(我想限制此用户,但我希望允许用户在一台计算机上打开同一会话的多个标签页。)

我可以实现一种服务器端机制,该机制在身份验证时生成随机密钥令牌,并与用户记录一起存储,并成为会话cookie。我可以使用它来确保只有经过身份验证的用户才能在一台计算机上登录(希望一台计算机上的多个选项卡仍在运行)。 flask-login是否已包含这样的方法,这通常是否适合我的要求?

2 个答案:

答案 0 :(得分:2)

我没有通过Flask-login's source,但正如你所说它使用Flask会话对象,这意味着Flask-login的这一部分是session cookie is cryptographically signed to protect against forgery以来的安全。 Flask将其称为“SecureCookie支持的会话”。数据未加密,但由于它已签名,因此用户可能无法对其进行修改。

这有一些优点:

  • 存储实际会话的负担转移到客户端。无需将会话存储在数据库中。如果您有许多匿名用户并且需要存储非关键状态,那就太棒了。
  • 应该是安全的
  • 通过使用浏览器扩展或手动,用户可以将会话从设备转移到另一个

但也有一些缺点:

  • 其他数据来回传输
  • 如果用户清除缓存,则会丢失所有会话数据。如果他们的设备崩溃,也一样。
  • 如果有足够的时间,由于攻击者可以访问多条消息及其签名,理论上可以通过强制攻击来猜测您的密钥。

确保您的SECRET_KEY足够强大。

答案 1 :(得分:1)

我最终做了我在问题中提出的建议。顺序是(1)将从会话cookie中提取认证令牌,(2)该认证令牌的用户是查询,(3a)如果未发现访问被禁止且登录页面显示,或(3b) )返回请求的页面。

当用户登录时,我致电

,而不是拨打login_user
def login_user_with_secret_session(user, remember=False, force=False):
    auth_session_token = random.getrandbits(128)
    auth_session_token = '%032x' % auth_session_token
    # store `auth_session_token` in user table
    set_user_auth_session_token(user, auth_session_token)
    return login_user(user, remember=remember, force=force)

另一项修改是login_manager.id_attribute = 'get_auth_session_token'

class User(Base, UserMixin):
    __table__ = user_table

    ...

    def get_auth_session_token(self):
        return self.auth_session_token

返回flask-login的身份验证令牌以进行访问。