Канонизировать URL-адреса для статического сайта с персональным доменом в GAE

Я запускаю статический сайт в GAE и использую собственный домен (назовем его example.com) с включенными сертификатами SSL. Я хочу канонизировать URL-адреса в https://www.example.com/. Это означает перехват любых запросов к myproject.appspot.com, обычному HTTP и / или голому домену и перенаправление на www через HTTPS.

Я понимаю, что невозможно поместить логику перенаправления в app.yaml, но в идеале я хотел бы сохранить там логику обслуживания статических файлов и иметь только код приложения для перенаправления. (В отличие от статической подачи в коде приложения.)

Вот что у меня есть на данный момент:

Содержание файла app.yaml:

runtime: python27
api_version: 1
threadsafe: true

handlers:
- url: /
  static_files: www/index.html
  upload: www/index.html

- url: /(.*)
  static_files: www/\1
  upload: www/(.*)

Содержание файла dispatch.yaml:

dispatch:
- url: "myproject.appspot.com/*"
  module: canonicalizer

Содержание файла canonicalizer.yaml:

module: canonicalizer
runtime: python27
api_version: 1
threadsafe: true

handlers:
- url: /.*
  script: canonicalizer.app

Содержание файла canonicalizer.py:

import webapp2

def get_redirect_uri(handler, *args, **kwargs):
    return 'https://www.example.com/' + kwargs.get('path')

app = webapp2.WSGIApplication([
    webapp2.Route('/<path:.*>',
    webapp2.RedirectHandler,
    defaults={'_uri': get_redirect_uri, '_code': 302}),
], debug=True)

Как видите, я пока только пытался реализовать перенаправление myproject.appspot.com. Мне не удалось заставить его работать; myproject.appspot.com по-прежнему обслуживает контент, а не перенаправляет в личный домен.

Я видел похожий SO вопрос и использовал его как основу для моего кода выше. Я довольно внимательно следил за ним, поэтому не уверен, что он устарел или в нем отсутствуют детали.

Я не очень хорошо знаком с webapp2. Также открыт для решений в другой структуре или даже на другом языке программирования.


person user2752467    schedule 15.01.2020    source источник


Ответы (2)


Как сказано в ответе sllopis, перенаправление HTTP на HTTPS может быть реализовано с помощью элемента secure: always.

Остальное, что я хотел сделать, нужно было сделать в коде приложения. Код в моем ответе был правильным, но у меня возникла некоторая путаница в отношении того, как службы работают в GAE, и в отношении dispatch.yaml. Вот мой последний код:

<application root>/app.yaml

runtime: python27
api_version: 1
threadsafe: true

handlers:
- url: /
  static_files: www/index.html
  upload: www/index.html
  secure: always
  redirect_http_response_code: 301

- url: /(.*)
  static_files: www/\1
  upload: www/(.*)
  secure: always
  redirect_http_response_code: 301

<application root>/dispatch.yaml

dispatch:
- url: "*.appspot.com/*"
  service: canonicalizer

- url: "example.com/*"
  service: canonicalizer

<application root>/canonicalizer/app.yaml

service: canonicalizer
runtime: python27
api_version: 1
threadsafe: true

handlers:
- url: /.*
  script: canonicalizer.app

<application root>/canonicalizer/canonicalizer.py

import webapp2

def get_redirect_uri(handler, *args, **kwargs):
    return 'https://www.justinforcentral.com/' + kwargs.get('path')

app = webapp2.WSGIApplication([
    webapp2.Route('/<path:.*>',
    webapp2.RedirectHandler,
    defaults={'_uri': get_redirect_uri, '_code': 301}),
], debug=False)

Это позволяет выполнять все перенаправления, сохраняя при этом возможность маршрутизации статического сайта через static_files обработчики.

Кстати, я также не осознавал, что простое выполнение gcloud app deploy . из корня приложения только развертывает службу по умолчанию. Чтобы развернуть все это, мне пришлось запустить gcloud app deploy . dispatch.yaml canonicalizer.

person user2752467    schedule 17.01.2020
comment
Спасибо @JustinLardinois за ваш ответ. Я уверен, что это поможет другим пользователям сообщества, столкнувшимся с той же проблемой. - person sllopis; 17.01.2020
comment
Последнее замечание важно - вы не могли увидеть, насколько вы были близки, без развернутой службы canonicalizer ... - person Dan Cornilescu; 17.01.2020
comment
Сейчас я работаю над другим приложением в среде выполнения Python 3. Вот примерный эквивалент canonicalizer webapp2 во Flask: amir.rachum.com / blog / 2016/08/27 / flask-redirect - person user2752467; 22.07.2020

Сопоставление пользовательских доменов с GAE

App Engine позволяет приложениям обслуживаться через собственный домен, например example.com, вместо адреса по умолчанию appspot.com. Вы можете создать сопоставление домена для своего приложения App Engine., чтобы использовать собственный домен.

Вам нужно будет сделать следующее:

  1. Подтвердите, что вы являетесь владельцем своего домена через Центр веб-мастеров
  2. Убедитесь, что ваш домен подтвержден.
  3. При необходимости делегируйте право владения своим доменом другим пользователям или сервисным аккаунтам.
  4. Подключите свой домен к приложению App Engine.
  5. Заполните форму, указав перечисленные записи ресурсов, включая их тип и каноническое имя (CNAME).
  6. Добавьте эту информацию в конфигурацию DNS вашего регистратора домена.

Защита личных доменов с помощью SSL

По умолчанию при сопоставлении личного домена своему приложению App Engine выдает управляемый сертификат SSL для HTTPS-подключений. Защита личных доменов с помощью SSL предлагает дополнительную информацию об этом.


Обработка запросов URL, которые не используют HTTPS

Любой обработчик URL-адресов может использовать параметр secure, включая обработчики сценариев и обработчики статических файлов. Если для secure установлено значение always, запросы URL, соответствующие этому обработчику и не использующие HTTPS , автоматически перенаправляются на URL HTTPS с тем же путем. Параметры запроса сохраняются для перенаправления.

Пример в app.yaml файле:

handlers:
- url: /youraccount/.*
  secure: always
  script: auto

Вывод

В результате после выполнения этих шагов вы должны правильно сопоставить личный домен с вашим сайтом App Engine, который использует сертификаты SSL для защиты личного домена.

Более того, добавив обработчик secure:always в файл app.yaml, любые URL-запросы, сделанные на вашем сайте App Engine, будут автоматически перенаправлены на URL-адрес HTTPS с тем же путем.


Обновление - перенаправьте все URL-адреса с помощью Google App Engine

Кредиты на Как перенаправить все URL-адреса с Google App Engine:

app.yaml

handlers:
- url: /.*
  script: main.py

main.py

import webapp2

class MainPage(webapp2.RequestHandler):
    def get(self):
        self.redirect("https://example.com", True)

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

Затем вы можете настроить этот код в соответствии со своими потребностями.

person sllopis    schedule 15.01.2020
comment
+1, потому что это работает для перенаправления на HTTPS, но не распространяется на перенаправление на www или с appspot.com. У меня уже был настроен личный домен и SSL, поэтому не стесняйтесь редактировать эти инструкции вне ответа. - person user2752467; 16.01.2020
comment
Вы также можете проверить Заблокируйте запросы от * .appspot.com и принудительно установите собственный домен в GAE и найдите один из наиболее подходящих вам ответов. - person sllopis; 16.01.2020
comment
Ваш ответ действительно решает проблему HTTPS. Поправьте меня, если я ошибаюсь, но я не думаю, что ваше изменение или ваш комментарий имеют отношение к оставшейся части моего вопроса. Я не пытаюсь перенаправить трафик из моего приложения на внешний сайт; Я пытаюсь перенаправить запросы на example.com или appspot.com на www.example.com. И я обслуживаю статический сайт, поэтому я не могу просто проверять os.environ['HTTP_HOST'] по каждому запросу. Мой вопрос заключается в том, есть ли способ сделать эту канонизацию, продолжая обрабатывать статический контент через app.yaml. - person user2752467; 17.01.2020