0

在寻找一种在我的应用程序中进行会话的好方法时,我发现了GAE BoilerplateGAE Sessions

GAEB 非常棒,但非常适合我的需求:我不需要 Federate Login 或默认用户结构,但我喜欢设计结构和他们解决一些问题的方式(路由、表单等)。

GAES 非常简单,但处理会话非常强大。我最喜欢的是将所有内容存储在 cookie 中的方式,在这种情况下,它将完整的用户实体存储在 cookie 中,因此在下一页调用中,不会完成其他数据存储命中:始终从 cookie 中读取用户数据(这种需要,显然是在用户更新某些内容时更新数据,这并不常见)。

另一方面,GAEB 仅存储用户 ID,然后在每次页面调用时检索用户名和用户电子邮件。这是它使用的 BaseHandler 代码的一部分(GAEB 使用 NDB 模型):

@webapp2.cached_property
def username(self):
    if self.user:
        try:
            user_info = models.User.get_by_id(long(self.user_id))
            if not user_info.activated:
                self.auth.unset_session()
                self.redirect_to('home')
            else:
                return str(user_info.username)
        except AttributeError, e:
            # avoid AttributeError when the session was delete from the server
            logging.error(e)
            self.auth.unset_session()
            self.redirect_to('home')
    return None

电子邮件也是如此,在 render_template 函数中它执行以下操作:

def render_template(self, filename, **kwargs):
    .... some code.....

    # set or overwrite special vars for jinja templates
    kwargs.update({
        'app_name': self.app.config.get('app_name'),
        'user_id': self.user_id,
        'username': self.username,
        'email': self.email,
        ... more vars ...
    })
    kwargs.update(self.auth_config)

似乎从数据存储中读取了 2 次(一次用于用户名,一次用于电子邮件),因为此功能使models.User.get_by_**field**(long(self.user_id))

我唯一不知道的确切含义是@webapp2.cached_property,这可能意味着所有这些数据存储读取都是从缓存中完成的,并且实际上不会命中数据存储。

有人可以告诉我将点击保存到数据库的更好解决方案是什么?似乎最好将所有用户数据都保存在 cookie 中(显然是安全的),并且不要在每次页面调用时都访问数据存储区,但也许我错了(我对 GAE 比较陌生)和所有这些对数据存储的读取被缓存,然后是免费的。

4

1 回答 1

1

强烈建议不要在 cookie 中保存会话数据:

  • 它必须随每个请求一起传输(移动连接速度慢)
  • 您可以传输到 GAE 的 HTTP 标头大小是有限的(如果我没记错的话是 64Kb)——这是您可以存储的数据的上限
  • 即使您加密并签署您的会话,您仍然容易受到回复攻击(您无法安全地执行注销)

我不知道您提到的实现,但我们的 CMS 中有一个会话实现,请参阅https://bitbucket.org/viur/server/src/b2e9e3dca3adabee97e1761d630600a387a02c44/session.py?at=master。一般的想法是生成一个随机字符串(用作会话标识符)。在会话加载时,会执行数据存储“按键获取”(已缓存,因此如果该对象仍在 memcache 中,它根本不会命中数据存储)。

并且仅当存储在会话中的数据发生更改或会话在过去 5 分钟内未更新时才执行保存。然后,您可以将用户对象的值复制到会话中,并且不会有额外的数据存储请求。

于 2013-07-17T19:56:45.440 回答