阻止来自* .appspot.com的请求并在Google App Engine中强制自定义域

时间:2009-09-01 21:26:12

标签: python google-app-engine redirect

如何阻止用户访问example.appspot.com上的应用并强制他们在example.com上访问它?我已经有example.com工作,但我不希望用户能够访问appspot域。我正在使用python。

5 个答案:

答案 0 :(得分:17)

您可以查看是否os.environ['HTTP_HOST'].endswith('.appspot.com') - 如果是,那么您将从something.appspot.com投放并可以发送重定向,或者根据需要更改您的行为。

您可以以各种方式(装饰器,WSGI中间件,从您的子类{{1}的中间基类继承)部署此检查和重定向 - 如果需要(或您选择的其他行为更改) } [[或者你当前正在使用的任何其他基本处理程序]]和方法名称与你的应用程序级处理程序类中的get和post不同,但是我认为这里的关键思想是{{1} }是由应用程序引擎框架根据CGI标准设置的,因此您可以依赖这些标准(类似地,WSGI基于它从os.environ中获取的值构建自己的环境)。

答案 1 :(得分:7)

上面发布的代码存在两个问题 - 它尝试重定向安全流量(自定义域不支持),当Google在您的appspot域上调用它们并且您提供301时,您的cron作业也会失败。

我在我的博客上发布了一个稍微修改过的版本: http://blog.dantup.com/2009/12/redirecting-requests-from-appid-appspot-com-to-a-custom-domain

为方便起见,我已将下面的代码包含在内。

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

def run_app(url_mapping):
    application = webapp.WSGIApplication(url_mapping, debug=True)
    application = redirect_from_appspot(application)
    run_wsgi_app(application)

def redirect_from_appspot(wsgi_app):
    """Handle redirect to my domain if called from appspot (and not SSL)"""
    from_server = "dantup-blog.appspot.com"
    to_server = "blog.dantup.com"

    def redirect_if_needed(env, start_response):

        # If we're calling on the appspot address, and we're not SSL (SSL only works on appspot)
        if env["HTTP_HOST"].endswith(from_server) and env["HTTPS"] == "off":

            # Parse the URL
            import webob, urlparse
            request = webob.Request(env)
            scheme, netloc, path, query, fragment = urlparse.urlsplit(request.url)
            url = urlparse.urlunsplit([scheme, to_server, path, query, fragment])

            # Exclude /admin calls, since they're used by Cron, TaskQueues and will fail if they return a redirect
            if not path.startswith('/admin'):
                # Send redirect
                start_response("301 Moved Permanently", [("Location", url)])
                return ["301 Moved Peramanently", "Click Here %s" % url]

        # Else, we return normally
        return wsgi_app(env, start_response)

    return redirect_if_needed

答案 2 :(得分:3)

def redirect_from_appspot(wsgi_app):
def redirect_if_needed(env, start_response):
    if env["HTTP_HOST"].startswith('my_app_name.appspot.com'):
        import webob, urlparse
        request = webob.Request(env)
        scheme, netloc, path, query, fragment = urlparse.urlsplit(request.url)
        url = urlparse.urlunsplit([scheme, 'www.my_domain.com', path, query, fragment])
        start_response('301 Moved Permanently', [('Location', url)])
        return ["301 Moved Peramanently",
              "Click Here" % url]
    else:
        return wsgi_app(env, start_response)
return redirect_if_needed  

答案 3 :(得分:1)

您可以通过以下方式覆盖example.com基类中的initialize方法,将其重定向到自定义域(此处为webapp2.RequestHandler):

def initialize(self, *a, **kw):
    webapp2.RequestHandler.initialize(self, *a, **kw)

    if self.request.host.endswith('appspot.com'):
        self.request.host = 'example.com'
        self.redirect(self.request.url, permanent=True)

答案 4 :(得分:0)

如果您使用的是webapp2,则可以使用DomainRoute轻松(取决于您的使用案例)解决方案。

如果这是您的网址:

url_map = [
    ('/', HomeHandler),
    ('/about', AboutHandler),
    ('/admin/(.+)', AdminHandler),
    MailForwardHandler.mapping(),
]
application = webapp2.WSGIApplication(url_map, debug=True)

并且管理员和邮件应该重定向,然后添加重定向路由,如下所示:

from webapp2_extras import routes

url_map = [
    routes.DomainRoute('appid.appspot.com', [
        routes.RedirectRoute('/', redirect_to='http://app.com', schemes=['http']),
        routes.RedirectRoute('/about', redirect_to='http://app.com/about', schemes=['http']),
    ],
    ('/', HomeHandler),
    ('/about', AboutHandler),
    ('/admin/(.+)', AdminHandler),
    MailForwardHandler.mapping(),
]
application = webapp2.WSGIApplication(url_map, debug=True)

根据规定,这将仅重定向http,不是 https。它根据需要使用永久重定向(301)。

您还可以将功能传递给redirect_toas described in the documentation,这可以让您在拥有大量规则时更轻松。