【问题标题】:GAE webapp2 session: the correct process of creating and checking sessionsGAE webapp2 session:创建和检查会话的正确过程
【发布时间】:2012-12-14 05:21:23
【问题描述】:

我尝试实现 GAE 的 webapp2 会话,但是关于它的文档似乎很少。根据http://webapp-improved.appspot.com/api/webapp2_extras/sessions.html,我的步骤如下:

1.配置并添加配置到主应用程序:

config = {}
config['webapp2_extras.sessions'] = {
    'secret_key': 'my_secret_key',
}
app = webapp2.WSGIApplication([...], config=config)

2.在登录处理程序中创建会话

# Delete existent session
  --> not mention in the tutorial
# member is found    
self.session_store = sessions.get_store(request=handler.request)
self.session['account'] = member.account

3.检查我程序中不同位置是否存在会话

if self.session['account']:
    # Session exists

4.用户注销时删除会话

--> not mentioned in the tutorial

我的问题:

  1. 我在会话创建过程中收到错误消息“...对象没有属性'会话'”(步骤 2)

  2. 如何在第 2 步和第 4 步中删除会话?

  3. 整个会话管理流程是否正确?

谢谢。

【问题讨论】:

    标签: google-app-engine session webapp2


    【解决方案1】:

    这是处理程序的示例以及如何使用 webapp2 额外会话

    带有 BaseHandler 和 MainHandler 的 main.py

    import webapp2
    from webapp2_extras import sessions
    
    class BaseHandler(webapp2.RequestHandler):              # taken from the webapp2 extrta session example
        def dispatch(self):                                 # override dispatch
            # Get a session store for this request.
            self.session_store = sessions.get_store(request=self.request)
    
            try:
                # Dispatch the request.
                webapp2.RequestHandler.dispatch(self)       # dispatch the main handler
            finally:
                # Save all sessions.
                self.session_store.save_sessions(self.response)
    
        @webapp2.cached_property
        def session(self):
            # Returns a session using the default cookie key.
            return self.session_store.get_session()
    
    class YourMainHandler(BaseHandler):
    
        def get(self):
    
            ....
            self.session['foo'] = 'bar'
    
    
        def post(self):
    
    
            foo = self.session.get('foo')
    

    如果你有一个单独的 login.py :

    .... other imports
    import main
    
    class Login(main.BaseHandler):
    
        def get(self):
    
            ....
            self.session['foo'] = 'bar'
    
    
        def post(self):
    
    
            foo = self.session.get('foo')
    

    【讨论】:

    • 非常感谢您的帮助。我仍在挣扎,但没有运气。假设我有一个模块“login.py”,其中包含类 Login(webapp2.RequestHandler) 用于处理用户登录。还有一个主模块“main.py”,其中包含类 MainPage(BaseHandler)。如何更改登录类?我在 login.py 中导入 main,并将类 Login(webapp2.RequestHandler) 更改为 Login(main.BaseHandler)。错误消息:“模块”对象没有属性“BaseHandler”
    • 这就是我所说的:错误消息:'module'对象没有属性'BaseHandler'
    • 在检查用户是否存在时,我真的不需要会话的用户名。因此,“foo = self.session.get('foo')”似乎并没有完成这项工作。那我该怎么做呢?此外,如何删除用户的会话(也不知道用户名)?感谢日志。
    • 我建议你学习 session 和 webapp2。给你一个最后的提示:当用户结束他的会话时,不要写入/保存会话并删除会话 cookie。
    • re:basehandler 问题,建议您在获得更多专业知识之前将所有内容保存在同一个文件中。
    【解决方案2】:

    这可能不是问题的直接答案,但这是我使用 gaesessions 而不是 GAE 的 webapp2 会话找到的解决方案,我想与大家分享。我们开始:

    1. 通过单击“下载 ZIP”按钮从 https://github.com/dound/gae-sessions 下载 gaesession。下载的文件是“gae-sessions-master.zip”。

    2. 解压缩文件(将创建一个目录“gae-sessions-master”),并将目录“gaessions”复制到应用程序的根目录(即“app.yaml”所在的位置)

    3. 在根目录下创建一个名为“appengine_config.py”的文件,内容如下(复制形式https://github.com/dound/gae-sessions/tree/master/demo):

      from gaesessions import SessionMiddleware
      
      # Original comments deleted ... 
      # Create a random string for COOKIE_KDY and the string has to
      # be permanent. "os.urandom(64)" function may be used but do
      # not use it *dynamically*.
      # For me, I just randomly generate a string of length 64
      # and paste it here, such as the following:
      
      COOKIE_KEY = 'ppb52adekdhD25dqpbKu39dDKsd.....'
      
      def webapp_add_wsgi_middleware(app):
          from google.appengine.ext.appstats import recording
          app = SessionMiddleware(app, cookie_key=COOKIE_KEY)
          app = recording.appstats_wsgi_middleware(app)
          return app
      
    4. 在用户登录时创建会话(变量account是用户的帐户):

      from gaesessions import get_current_session
      session = get_current_session()
      if session.is_active():
          session.terminate()
      # start a session for the user (old one was terminated)
      session['account'] = account
      
    5. 检查用户的会话是否存在,如果存在,返回用户的账号:

      from gaesessions import get_current_session
      def checkSession():
          session = get_current_session()
          if session.is_active():
              return session['account']
          return False
      
    6. 用户注销时删除会话:

      def logout():
          session = get_current_session()
          if session.is_active():
              session.terminate()
      
    7. 最后,您可以创建一个 cron 作业来定期清理过期的会话:

    cron.yaml:

    - description: daily session cleanup
      url: /clean_up_sessions
      schedule: every day 3:00
      timezone: ... (Your time zone)
    

    功能:

    from gaesessions import delete_expired_sessions
    class clean_up_sessions(webapp2.RequestHandler):
        def get(self):
            while not delete_expired_sessions():
                pass
    

    希望这会有所帮助。

    【讨论】:

    • 为什么使用 gae-sessions 而不是 webapp2_extras.sessions? gae-sessions 将自己与一些会话系统进行比较,但不与 webapp2 的会话进行比较。
    • 非常感谢,罗姆兹。我不知道有 webapp2_extras.sessions。我试试看。
    • 在我的应用验证中,在数据存储中创建一个唯一模型,并将密钥保存在 UserToken 中,当用户更改密码并注销时,他无法再次登录
    【解决方案3】:

    在您的RequestHandler 覆盖dispatch: 从 webapp2_extras 导入会话

    def dispatch(self):
    
        self.session_store = sessions.get_store(request=self.request)
    
        try:
            webapp2.RequestHandler.dispatch(self)
        finally:
            self.session_store.save_sessions(self.response)
    

    并创建一个名为sessionwebapp2.cached_property

    @webapp2.cached_property
    def session(self):
        return self.session_store.get_session(backend="<whatever you want here>")
    

    当你想访问会话值时,你可以self.session[&lt;key&gt;]

    当用户登录时,您可以调用:

     self.auth.get_user_by_password(auth_id, password, remember=True,
                                               save_session=True)
    

    这将负责摆脱旧会话并为您创建新会话,或者:

    self.auth.set_session(self.auth.store.user_to_dict(self.user), remember=True)
    

    就注销而言,您只需要调用:

    self.auth.unset_session()
    

    【讨论】:

    • 什么是self.auth
    • 看来self.auth来自here
    猜你喜欢
    • 2015-03-16
    • 2014-10-03
    • 2012-08-15
    • 2016-06-05
    • 2014-08-04
    • 2020-11-16
    • 2018-02-03
    • 2015-12-23
    • 2012-07-14
    相关资源
    最近更新 更多