背景:我有一个非常简单的基于投票的网站设置的核心功能,并且在金字塔中利用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'))
谢谢!
要想在金字塔上集成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_key
和 session.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来获得投票权已经不可取了。
安全性并不是要建立完美的不可破解的系统,而是要建立一个绕过它的成本实际上高于这样做的收益的系统。
使用cookie来进行这种控制,即使是最简单的攻击(比如使用不同的浏览器:)也无法防止。但你似乎知道这一点,实际上并不在意,所以我想应该没问题。
每次用户投票时,在cookie中添加一个字段(你还应该将其年龄限制设置为至少一周),其值为当前日期。
下一次用户试图投票时,你会检查今天是周六还是周日(根据用户时间设置),如果该字段存在,以及该值是否超过一天。
如果您将cookie的有效期设置为下一个星期六,您将有一个额外的验证机制,因为如果是星期六,cookie无论如何都不会有效:)