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

14 投票
5 回答
5467 浏览
提问于 2025-04-15 14:00

我该怎么做才能阻止用户访问我的应用在 example.appspot.com 上,而强制他们只能通过 example.com 来访问呢?我已经把 example.com 设置好了,但我不想让用户能通过 appspot 域名来访问这个应用。我是在用 Python 编程。

5 个回答

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  

当然可以!请把你想要翻译的内容发给我,我会帮你用简单易懂的语言解释清楚。

7

上面发布的代码有两个问题 - 它试图重定向安全流量(这在自定义域名上是不支持的),而且当谷歌在你的appspot域名上调用你的定时任务时,如果你返回一个301状态码,定时任务就会失败。

我在我的博客上发布了一个稍微修改过的版本: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
17

你可以检查一下 os.environ['HTTP_HOST'].endswith('.appspot.com') 这个条件。如果是这样的话,说明你正在从 something.appspot.com 这个地址提供服务,这时你可以发送一个重定向,或者根据需要改变你的行为。

你可以用多种方式来实现这个检查和必要时的重定向(或者其他你想要的行为改变),比如使用装饰器、WSGI中间件,或者从你自己定义的一个中间基类继承,这个基类是从 webapp.RequestHandler 继承来的(或者你当前使用的其他基类),并且在你的应用级处理类中使用不同于get和post的方法名,等等。但我认为这里的关键点是 os.environ 是由应用引擎框架根据CGI标准设置的,所以你可以依赖这些标准(同样,WSGI也会根据它从os.environ中获取的值构建自己的环境)。

撰写回答