【问题标题】:Restore session in CherryPy by specific id通过特定 ID 在 CherryPy 中恢复会话
【发布时间】:2014-08-21 21:11:28
【问题描述】:

我正在通过 CherryPy 做一个 RESTful Web 服务。由于客户端并不总是浏览器并且可能无法存储 cookie,所以我计划获取 CherryPy 的会话 id 并通过 HTTP GET/POST 作为令牌传递。当客户端使用此令牌(会话 ID)向 CherryPy 发送请求时,它可以像 cookie 一样恢复会话,服务器端可以获得身份验证或任何有状态数据。

我的问题是,如何通过特定 id 恢复 CherryPy 会话?

【问题讨论】:

    标签: session cherrypy


    【解决方案1】:

    前面的例子对我不起作用(至少对于文件会话)。可能是因为当前版本的cherrypy 禁止已经初始化会话的会话初始化。然而,真正起作用的是:

    cherrypy.session.id = token
    cherrypy.session._load()
    

    我知道这很脏,因为调用了私有方法,但这是我找到的唯一方法。

    【讨论】:

      【解决方案2】:

      受 saaj 的启发,我找到了一个可行的解决方案。试试这个...

      import cherrypy.lib
      
      config = {
        'global' : {
          'server.socket_host' : '127.0.0.1',
          'server.socket_port' : 8080,
          'server.thread_pool' : 4,
          'tools.sessions.on': True,
          'tools.sessions.storage_type': "file",
          'tools.sessions.storage_path': "adf"
        }
      }
      
      
      class Helloworld:
          @cherrypy.expose
          def make(self, token=''):
              '''You can try open it from another browser 
              once set the value in /counter
              '''
      
              if(token == ''):
                  cherrypy.lib.sessions.init()
                  # take this token and put in the url 127.0.0.1:8080/make/ + token
                  return cherrypy.session.id
              else:
                  #send two requests with the token. 1. to set a session var 
                  #  and 2. to retrieve the var from session
                  cherrypy.lib.sessions.init(self, id=token)
      
                  print('do something')
                  # on the second request check the value after init and it's HI!
                  cherrypy.session['something'] = 'HI'            
      
              return token
      
      if __name__ == '__main__':
        cherrypy.quickstart(Helloworld(), '/', config)
      

      希望这会有所帮助!

      【讨论】:

        【解决方案3】:
        #!/usr/bin/env python
        # -*- coding: utf-8 -*-
        
        
        import cherrypy.lib
        
        
        config = {
          'global' : {
            'server.socket_host' : '127.0.0.1',
            'server.socket_port' : 8080,
            'server.thread_pool' : 4
          }
        }
        
        
        class App:
        
          @cherrypy.expose
          @cherrypy.config(**{'tools.sessions.on': True})
          def counter(self):
            if 'counter' not in cherrypy.session:
              cherrypy.session['counter'] = 0
            cherrypy.session['counter'] += 1
        
            return 'Counter: {0}<br/>Session key: {1}'.format(
              cherrypy.session['counter'], 
              cherrypy.request.cookie['session_id'].value
            )
        
          @cherrypy.expose
          def recreate(self, token):
            '''You can try open it from another browser 
            once set the value in /counter
            '''
            cherrypy.request.cookie['session_id'] = token
            cherrypy.lib.sessions.init()
            # now it should be ready
            return 'Counter: {0}'.format(cherrypy.session['counter'])
        
        
        
        if __name__ == '__main__':
          cherrypy.quickstart(App(), '/', config)
        

        【讨论】:

        • 他提到请求不是来自浏览器,不能使用cookies来存储会话ID。
        • 嗨 saaj,我专注于设置 cookie['session_id'] = token 并调用 init()。经过测试,它不起作用,无法取回现有的会话内容。 PS。我正在使用 curl 和 HTTP GET 来测试令牌。
        • @AndrewKloos 您的评论不相关,因为代码是伪造的与客户端功能无关的请求 cookie。
        • @Takol 无论您使用 curl 还是其他浏览器进行演示,都应该没有任何区别。内部会话处理在/recreate 关闭,它是手动触发的。演示代码工作正常:启动应用程序,打开 /counter,刷新几次,复制令牌,在另一个代理打开 /recreate?token=TOKEN。确保演示代码适合您,然后将该方法移植到您的真实代码中。
        • @Takoi 我明白了......很好地重新创建 + 令牌返回错误。 KeyError:'计数器'
        猜你喜欢
        • 2019-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-12
        • 2016-06-25
        相关资源
        最近更新 更多