背景
我拥有基于投票的非常简单的网站设置的核心功能,并且在使用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'))
谢谢!
答案 0 :(得分:2)
要在金字塔上集成Cookie会话,请查看pyramid_beaker
为了保证仅使用cookie的完整性(并避免用户访问cookie数据),您应该使用加密的cookie(请查看Session Based Cookie和Encryption Options)。
您的主要配置看起来有点像这样:
[app:main]
...
session.type = cookie
session.key = SESSION
session.encrypt_key = R9RD9qx7uzcybJt1iBzeMoohyDUbZAnFCyfkWfxOoX8s5ay3pM
session.validate_key = pKs3JDwWiJmt0N0wQjJIqdG5c1XsHSlauM6T2DfB8FqOifsWZN
...
session.key
只是Cookie的名称。改变你想要的任何东西
上面的session.encrypt_key
和session.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无论如何都不会有效:)