如何在Google App Engine Python应用中共享模块间的会话?

8 投票
1 回答
1592 浏览
提问于 2025-04-18 13:45

我正在尝试在Google App Engine上制作一个基本的应用程序,这个应用有两个模块,使用的是Google App Engine的模块功能(https://developers.google.com/appengine/docs/python/modules/),并且它们之间可以共享会话信息:

模块:

  • 模块 1 - 登录页面:这是一个简单的页面,里面有一个登录表单。如果用户有效,我会创建一个会话,然后用户会被重定向到仪表盘页面(模块 2)
  • 模块 2 - 仪表盘页面:这个页面会显示一条消息,告诉用户这个模块是否能读取会话变量中的数据

问题是,在仪表盘模块中,登录页面(模块 1)创建的会话数据并不存在。

在Google App Engine中,是否可以在两个或多个模块之间访问会话数据?

来源:

baseHandler.py

import webapp2
from webapp2_extras import sessions

class BaseHandler(webapp2.RequestHandler):

    def render_template(self, view_filename, params=None):
        params = {}
        path = os.path.join(os.path.dirname(__file__), 'views', view_filename)
        self.response.out.write(template.render(path, params))

    def display_message(self, message):
        """Utility function to display a template with a simple message."""
        params = {}
        self.render_template('message.html', params)

    def dispatch(self):
        # Get a session store for this request.
        self.session_store = sessions.get_store(request=self.request)

        try:
            # Dispatch the request.
            webapp2.RequestHandler.dispatch(self)
        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()

模块 1(登录) main.py

from google.appengine.ext import ndb
import webapp2
from webapp2_extras.security import hash_password

import logging
import os
import sys
import jinja2

from src.basehandler import BaseHandler
from src.user import User

JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
    extensions=['jinja2.ext.autoescape']
)

class MainPage(BaseHandler):

    def get(self):
        template_values = {}
        template = JINJA_ENVIRONMENT.get_template('templates/index.html')
        self.response.write( template.render( template_values ) )


    def post(self):
        email_address = self.request.get('input-email')
        password = self.request.get('input-password')

        password = hash_password( password, 'sha1', salt=None, pepper=None )

        qry = User.query(
            ndb.AND(User.email_address == email_address,
                    User.password == password
            )
        ).fetch()

        if qry:
            self.session['loggedin'] = True
            self.redirect('http://dashboard.myURL.appspot.com/')

        else:
            self.redirect('/?error=invaliduser')

config = {}
config['webapp2_extras.sessions'] = {
    'secret_key': 'my-super-secret-key',
}

app = webapp2.WSGIApplication([
    ('/', MainPage)
], debug=True, config=config )

模块 2(仪表盘) main.py

from google.appengine.ext import ndb
import webapp2

import logging
import os
import sys
import jinja2

from src.basehandler import BaseHandler
from src.user import User

JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
    extensions=['jinja2.ext.autoescape']
)

class Main(BaseHandler):

    def get(self):
        msg = ''

        if not self.session.get('loggedin'):
            msg = 'There is not session'

        else:
            msg = 'There is a session'

        template_values = { 'msg': msg }
        template = JINJA_ENVIRONMENT.get_template('templates/index.html')
        self.response.write( template.render( template_values ) )

config = {}
config['webapp2_extras.sessions'] = {
    'secret_key': 'my-super-secret-key',
}

app = webapp2.WSGIApplication([
    ('/', Main)
], debug=True, config=config )

任何帮助都很欢迎,如果有拼写错误请见谅

1 个回答

8

默认情况下,webapp2_extra.sessions使用基于cookie的会话。这些会话会绑定到特定的域名。你的模块可能分别在module1.yourapp.appspot.com和module2.yourapp.appspot.com(这是我的猜测)。第二个模块无法看到第一个模块设置的cookie。

在你的配置中,试着为cookie设置一个域名。

config['webapp2_extras.sessions'] = {
    'secret_key': 'my-super-secret-key',
     cookie_args': { 
         'domain' : "yourapp.appspot.com"
}

文档中提到:

 - domain: Domain of the cookie. To work accross subdomains the
   domain must be set to the main domain with a preceding dot, e.g.,
   cookies set for `.mydomain.org` will work in `foo.mydomain.org` and
   `bar.mydomain.org`. Default is None, which means that cookies will
   only work for the current subdomain.

来源:https://code.google.com/p/webapp-improved/source/browse/webapp2_extras/sessions.py

或者你也可以使用其他的后端,比如memcache或datastore。如果你的会话包含敏感信息,使用这些会比较好。

撰写回答