基于cookie实现金字塔中的“每日一票”系统

时间:2013-06-07 16:27:33

标签: python session cookies pyramid voting

背景

我拥有基于投票的非常简单的网站设置的核心功能,并且在使用sqlite数据库的金字塔中运行良好。此应用程序的最后一个要求是每个用户每天只允许一次投票。已经规定必须通过cookie完成,并且不允许任何用户在星期六或星期日投票。

我目前正在使用UnencryptedCookieSessionFactoryConfig进行会话管理和处理Flash消息。

问题:

我已经确定我需要以下功能,但无法确定金字塔的哪些模块可能提供它(或者我应该在其他地方寻找):

  • 为浏览器会话之间存在的每个用户创建一个cookie(我知道这是一种不安全的方法,可以防止多次投票。没关系。)

  • 每位用户每天只需投票一次。

  • 24小时后再向用户投票。

  • 如果星期几=星期六或星期日,则禁止所有投票(在任何cookie检查逻辑之前使用datetime()检查应该是微不足道的。

其他信息:

我当前的数据库架构如下,并且必须保持这种状态:

create table if not exists games (
    id integer primary key autoincrement,
    title char(100) not null,
    owned bool not null,
    created char(40) not null
);

create table if not exists votes (
    gameId integer,
    created char(40) not null,
    FOREIGN KEY(gameId) REFERENCES games(id)
);

并且当前的投票功能如下:

@view_config(route_name='usevote')
def usevote_view(request):
    game_id = int(request.matchdict['id'])
    request.db.execute('insert into votes (gameId,created) values (?,?)',
                (game_id,now))
    request.db.commit()
    request.session.flash('Your vote has been counted. You can vote again in 24 hours.')
    return HTTPFound(location=request.route_url('list'))

谢谢!

2 个答案:

答案 0 :(得分:2)

仅限cookie的会话数据

要在金字塔上集成Cookie会话,请查看pyramid_beaker

为了保证仅使用cookie的完整性(并避免用户访问cookie数据),您应该使用加密的cookie(请查看Session Based CookieEncryption Options)。

您的主要配置看起来有点像这样:

[app:main]
...
session.type = cookie
session.key = SESSION
session.encrypt_key = R9RD9qx7uzcybJt1iBzeMoohyDUbZAnFCyfkWfxOoX8s5ay3pM
session.validate_key = pKs3JDwWiJmt0N0wQjJIqdG5c1XsHSlauM6T2DfB8FqOifsWZN
...

session.key只是Cookie的名称。改变你想要的任何东西

上面的session.encrypt_keysession.validate_key只是大型随机字符串的示例。 您应该自己生成它们并将它们保密。

此外,要正确加密Cookie,您需要AES密码实现。安装pycrypto应该这样做:

pip install pycryto

此外,您创建wsgi应用程序的main函数应更改为以下内容:

from pyramid_beaker import session_factory_from_settings
...

def main(global_config, **settings):
    ...
    config = Configurator(settings=settings)
    ...
    config.set_session_factory(session_factory_from_settings(settings))

现在,您可以将cookie数据直接存储到客户端浏览器中,避免数据被篡改。解决问题的简单解决方案是将此cookie设置为永不过期,存储他最后一次投票的日期,并根据今天的哪一天以及他上次投票的日期进行检查

主要问题

现在的主要问题是处理删除cookie,使用其他浏览器或简单使用浏览器的隐身窗口(chrome)或私人导航(firefox)的用户。此用户似乎是您系统的新用户,因此可以再次投票。

IMO解决您需要拥有服务器端控制权或惩罚用户的方式,删除cookie实际上会使他的生活更加艰难,以至于不再需要删除cookie来获得投票。< / p>

安全不是关于完美不可攻击的系统,而是建立系统,绕过它的成本实际上高于实现它的好处。

答案 1 :(得分:0)

使用cookie进行这种控制并不能阻止即使是最简单的攻击(例如使用不同的浏览器:))。但你似乎知道它而不是真正关心所以它应该没问题我想:

每次用户投票时,都会在Cookie中添加一个字段(您还应该将其年龄限制设置为至少一周),并使用当前日期的值。

下次用户尝试投票时,您会检查是否是周六或周日(根据用户时间设置),该字段是否存在以及该值是否超过一天。

如果你将cookie的有效性设置为下周六,你将有一个额外的验证机制,因为如果它是星期六,cookie无论如何都不会有效:)