Блокировать запросы от *.appspot.com и принудительно настраивать собственный домен в Google App Engine

Как я могу запретить пользователю получать доступ к моему приложению на example.appspot.com и заставить их получить к нему доступ на example.com? У меня уже есть example.com, но я не хочу, чтобы пользователи имели доступ к домену appspot. Я использую python.

Ответы

Ответ 1

Вы можете проверить, если os.environ['HTTP_HOST'].endswith('.appspot.com') - если да, то вы отсылаете от something.appspot.com и можете отправлять перенаправление или иным образом изменять свое поведение по своему желанию.

Вы можете развернуть эту проверку и перенаправить-если необходимо (или другую модификацию поведения по вашему выбору) любым из способов (декораторы, промежуточное ПО WSGI, наследование из промежуточного базового класса ваших подклассов webapp.RequestHandler [ [или любой другой класс базового обработчика, который вы используете в настоящее время]] и имена методов, отличные от того, как получить и опубликовать в своих классах обработчика уровня приложения, и другие), но я думаю, что ключевая идея здесь заключается в том, что os.environ задается платформу движка приложения в соответствии со стандартами CGI, и поэтому вы можете полагаться на эти стандарты (аналогично WSGI создает свою собственную среду на основе значений, которые она выбирает из os.environ).

Ответ 2

В приведенном выше коде есть две проблемы: он пытается перенаправить защищенный трафик (который не поддерживается на пользовательских доменах), а также ваши задания cron не удастся, когда Google вызовет их в домене 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

Ответ 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  

Ответ 4

Вы можете перенаправить его в свой собственный домен (здесь 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)

Ответ 5

В случае, если вы используете webapp2, немного проще (в зависимости от вашего варианта использования) можно использовать его DomainRoute.

Если это ваша карта URL:

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_to, как описано в документации, что должно облегчить ее, когда у вас много правил.