【问题标题】:Canonicalize URLs for static site with custom domain in GAE在 GAE 中使用自定义域规范化静态站点的 URL
【发布时间】:2020-05-01 18:36:10
【问题描述】:

我在 GAE 上运行一个静态站点,并使用启用了 SSL 证书的自定义域(我们称之为example.com)。我想将 URL 规范化为 https://www.example.com/。这意味着捕获对myproject.appspot.com、纯HTTP 和/或裸域的任何请求,并通过HTTPS 重定向到www。

我知道不可能将重定向逻辑放在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 仍然提供内容,而不是重定向到自定义域。

我看到a similar SO question 并将其用作我上面代码的基础。我非常密切地关注它,所以我不确定它是否过时或缺少细节。

我对 webapp2 不是很熟悉。也对不同框架甚至不同编程语言的解决方案持开放态度。

【问题讨论】:

    标签: google-app-engine redirect google-cloud-platform web2py canonicalization


    【解决方案1】:

    正如 sllopis 在他们的回答中所说,HTTP 到 HTTPS 的重定向可以通过 secure: always 元素实现。

    我想做的其他事情需要在应用代码中完成。我的答案中的代码在正确的轨道上,但我对服务在 GAE 中的工作方式以及dispatch.yaml 有一些困惑。这是我的最终代码:

    &lt;application root&gt;/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
    

    &lt;application root&gt;/dispatch.yaml

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

    &lt;application root&gt;/canonicalizer/app.yaml

    service: canonicalizer
    runtime: python27
    api_version: 1
    threadsafe: true
    
    handlers:
    - url: /.*
      script: canonicalizer.app
    

    &lt;application root&gt;/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。

    【讨论】:

    • 感谢@JustinLardinois 的回答。我相信这会对遇到相同问题的其他社区用户有所帮助。
    • 最后一点很重要 - 如果没有部署规范化器服务,您将无法看到自己有多接近...
    • 我现在正在 Python 3 运行时中开发一个不同的应用程序。这是 webapp2 规范化器的大致 Flask 等效项:amir.rachum.com/blog/2016/08/27/flask-redirect
    【解决方案2】:

    Mapping Custom Domains to GAE

    App Engine 允许应用程序通过自定义域(例如example.com)而不是默认的appspot.com 地址来提供服务。您可以创建一个 domain mapping for your App Engine app 以便它使用自定义域。

    您需要执行以下操作:

    1. 通过 Webmaster Central 验证您是域的所有者
    2. 确保您的域已经过验证。
    3. 如果需要,将您的域的所有权委托给其他用户或服务帐户。
    4. 将您的域映射到您的 App Engine 应用程序。
    5. 用列出的资源记录填写表格,包括它们的类型和规范名称(CNAME)。
    6. 将此信息添加到您的域注册商的 DNS 配置中。

    Securing Custom Domains with SSL

    默认情况下,当您将自定义域映射到应用时,App Engine 会为 HTTPS 连接的 SSL 颁发托管证书。 Securing your custom domains with SSL 提供了更多相关信息。


    Handling URL requests that do not use HTTPS

    任何 URL 处理程序都可以使用secure 设置,包括脚本处理程序和静态文件处理程序。如果secure 设置为always,URL 请求与此处理程序匹配但不使用 HTTPS会自动重定向到具有相同路径的 HTTPS URL。为重定向保留查询参数。

    app.yaml 文件中的示例:

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

    结论

    因此,按照这些步骤操作后,您应该有一个自定义域正确映射到您的 App Engine 站点,该站点使用 SSL 证书来保护自定义域。

    此外,通过在您的 app.yaml 文件中添加 secure:always 处理程序,针对您的 App Engine 站点发出的任何 URL 请求都将自动重定向到具有相同路径的 HTTPS URL。


    更新 - 使用 Google App Engine 重定向所有网址

    致How to redirect all URLs with 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)
    

    然后,您可以根据需要调整此代码。

    【讨论】:

    • +1 因为这确实适用于重定向到 HTTPS,但它不包括重定向到 www 或从 appspot.com 重定向。我已经有一个自定义域和 SSL 设置,所以请随时从答案中编辑这些说明。
    • 您也可以查看Block requests from *.appspot.com and force custom domain in GAE 并找到最适合您的答案之一。
    • 您的回答确实解决了 HTTPS 问题。如果我错了,请纠正我,但我认为您的编辑或您的评论与我的问题的其余部分无关。我不想将流量从我的应用程序重定向到外部站点;我正在尝试将请求重定向到example.com 或appspot.com 到www.example.com。而且我提供的是一个静态站点,所以我不能简单地检查每个请求的os.environ['HTTP_HOST']。我的问题是问是否有办法在通过app.yaml 处理静态内容的同时进行规范化。
    猜你喜欢
    • 2014-11-28
    • 2017-01-20
    • 2011-06-29
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多