在金字塔中实现基于Cookie的 "每日一票 "系统。

问题描述 投票:2回答:2

背景:我有一个非常简单的基于投票的网站设置的核心功能,并且在金字塔中利用sqlite数据库运行良好。

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

我现在使用的是 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'))

谢谢!

python session cookies pyramid voting
2个回答
3
投票

只在cookies上显示会话数据

要想在金字塔上集成cookie会话,请看以下内容 金字塔烧杯

为了保证只使用cookie的完整性(避免用户窥探cookie数据),你应该使用加密的cookie(看看进入的 基于会话的Cookie加密选项).

你的主配置看起来像这样。

[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

还有你的 main 创建wsgi应用程序的函数应该改成这样。

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来获得投票权已经不可取了。

安全性并不是要建立完美的不可破解的系统,而是要建立一个绕过它的成本实际上高于这样做的收益的系统。


1
投票

使用cookie来进行这种控制,即使是最简单的攻击(比如使用不同的浏览器:)也无法防止。但你似乎知道这一点,实际上并不在意,所以我想应该没问题。

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.