2013-02-13 82 views
6

我有一个Flask应用程序,与Nginx + WSGI(FastCGI & Gevent)一起服务并使用标准Flask会话。我做不是使用session.permanent=True或任何其他额外的选项,但简单地设置SECRET_KEY在默认配置。恒定瓶会话ID

我做不是保存会话中的任何(键,值)对,只依赖于SID = session['_id']条目来识别返回的用户。我用下面的代码读取SID

@page.route ('/') 
def main (page='home', template='index.html'): 

    if not request.args.get ('silent', False): 
     print >> sys.stderr, "Session ID: %r" % session['_id'] 

我提出以下意见:

  1. 对于相同的IP地址,但不同的浏览器我得到不同的SIDs - 这是预期;
  2. 对于不同的IP &同一浏览器我再次有不同的SIDs - 预期;
  3. 对于具有相同浏览器的相同IP地址,我得到相同的SID - 也是预期的;现在

点,(3)是有趣的,因为即使删除相应的cookie中的SID保持不变!在某种程度上,即使这可能是可以理解的,但实际上我期望SID在不同的cookie之间进行更改。但我看到的唯一区别是,

session.new is True 

的cookie的删除后立即第一请求。即使这是非常期望的;但鉴于这些事实,我面临着以下问题:

  1. 这是否意味着,对于不同用户坐在相同 IP背后(具有相同的浏览器配置),我的后端会误认为是该相同用户?

  2. 如果点(1)的情况下,这些“粘性”当前会话的行为实际上是相当愉快的,因为这避免了仅仅是因为他们删除了相应的cookie我的用户可能会失去存在的数据的情况。

    他们仍然可以通过使用同一浏览器从同一网络重新访问该网站来节省时间。我喜欢那个,但只有如果点(1)是不是的情况。

  3. 我认为点(1)实际上会咬我,结论实际上是否会在会话中保存一个token,并因此接受用户可以通过简单地删除他的cookie来炸掉自己的命运?

  4. 或者有没有办法告诉Flask给每个新鲜的饼干不同的SIDs

其实,这个问题引起,因为我用冲击负荷的服务,这是模拟不同用户(同一IP),但我的后端不断看到它们作为一个用户,因为相应SIDs人全部都一样。

的应用可以在http://webed.blackhan.ch测试(其中经发布将移动https://notex.ch [基于浏览器的文本编辑器])。谢谢您的回答。

回答

5

看起来你正在使用Flask-Login扩展。下面是生成id令牌的代码:

def _create_identifier(): 
    base = unicode("%s|%s" % (request.remote_addr, 
           request.headers.get("User-Agent")), 'utf8', errors='replace') 
    hsh = md5() 
    hsh.update(base.encode("utf8")) 
    return hsh.digest() 

它基本上只是md5(ip_address + user_agent)

烧瓶使用Werkzeug's secure cookies来存储此标识符。安全cookie(如其名称所暗示的)安全:

该模块实现了一个不能从客户端改变的cookie,因为它添加了服务器检查的校验和。如果您拥有的是用户标识或用于标记已登录用户的内容,则可以将其用作会话替换。

+0

谢谢你的回答:的确,我正在使用'Flask-Login',我想这解释了为什么我只看到一个具有相同(IP,User-Agent)组合的用户。我在cookie中引入了一个令牌,以便在这种情况下能够区分。 – hsk81 2013-02-13 10:56:58

+0

@ hsk81:这很奇怪。我很确定Flask的会话被分配了随机ID,以防止像这样的问题。 – Blender 2013-02-13 10:58:08

+0

不知道,即使在删除cookie后,它仍会给我一个'session ['_ id']'的常量值。我的印象是,没有这样的随机化,或者以某种方式'session ['_ id']'是访问会话身份的错误方式。我还没有找到关于* canonical *方法应该是什么的参考,并且只是在cookie中查看Flask创建和使用的那个:'_id''。我可能会忽略文档中的某些内容。 – hsk81 2013-02-13 11:09:02

0

session['_id']不是实际的会话标识符。这只是Flask-Login用来实现Session Protection的一个值。

标准 Flask会话没有SID--因为会话的实际内容存储在cookie本身中,所以它没有任何用处。另见this