7

原始问题


App Engine SDK 1.6.5
Python 2.7
webapp2

我已经实现了 webapp2 方案来保护页面到 https。问题是,当用户说 http://site/login 而不是 https://site/login 时,由于方案无法识别路线,他们会收到 404 错误。

示例 main.py

#  Libraries
import webapp2

#  Local Controllers
from controllers.HomeHandler import HomeHandler
from controllers.LoginHandler import LoginHandler

app = webapp2.WSGIApplication([
    webapp2.Route(r'/', HomeHandler),
    webapp2.Route(r'/login', LoginHandler, schemes=['https'], name='login')
], debug=True)

我在 https 路由下面添加了另一个路由/控制器来捕获 http 请求:
webapp2.Route(r'/login', RouteLogin)

RouteLogin.py

#  Libraries
import webapp2

class RouteLogin(webapp2.RequestHandler):
    def get(self):
        self.redirect('https://site.appspot.com/login')

这可行,但似乎应该有更好的方法来做到这一点。就像在 Apache Web 服务器上使用 htaccess。这太像我喜欢的黑客了。我真的不喜欢我的代码中的硬编码 URL。更不用说 2 个登录请求没什么大不了的,但可能还有其他示例最终导致成本过高。

注意 1:如果您正在查看此解决方案,请注意使用 HTTPS 方案还意味着如果不删除 SCHEME 或配置为 dev 设置的变量,您将无法使用开发控制台。

注意 2:我能够获得一种编程方式来提供 HTTPS 而不是 HTTP。我在下面的评论中走在了正确的轨道上,但它需要一个论点。

webapp2.uri_for('login', _scheme='https')
这将为您提供正确的https://someapp.appspot.com/login网址。不幸的是,它没有解决我的主要问题,即如何处理人们在没有 https 的情况下将 url 键入地址栏中并收到错误,除非我使用上面的 hack。所以我仍在寻找将收入请求路由到 HTPPS 的 WSGI 方式。

编辑:添加注释 1 并澄清标题,我认为很明显我使用的是源代码中的 WSGI 而不是 CGI。

4

2 回答 2

8

在 app.yaml 中设置 URL,而不是在代码中。请参阅https://developers.google.com/appengine/docs/python/config/appconfig#Secure_URLs

例如:

handlers:

- url: /foo/.*
  script: accounts.py
  secure: always

这会将 HTTP 重定向到 HTTPS。

于 2012-05-30T09:46:37.660 回答
1

这是我在测试这个问题时使用的工作代码。

注意:开发 Web 服务器(在撰写本文时为 v1.6.5)不支持 https,因此您的 WSGI 路由将需要删除方案才能在开发环境中工作。您可以在部署之前将它们添加回来,或者创建一个变量来设置检查环境的方案,如下所示。

您可以通过将 app.yaml 定义为
app.yaml来让 App Engine Python 重新路由请求

application: cgi-vs-wsgi
version: 1
runtime: python27
api_version: 1
threadsafe: yes

libraries:
- name: webapp2
  version: latest

handlers:

- url: /profile
  script: main.app
  secure: always

- url: /login
  script: main.app
  secure: always

- url: /.*
  script: main.app

然后在 main.py 中,你可以像往常一样声明你的 WSGI 处理程序:

主文件

import webapp2
import os

# Models
from models.Shout import Shout

# Controllers
from controllers.HomeHandler import HomeHandler
from controllers.LoginHandler import LoginHandler
from controllers.ProfileHandler import ProfileHandler

if os.environ['SERVER_SOFTWARE'].startswith('Development'):
    app_scheme = 'http'
else:
    app_scheme = 'https'

app = webapp.WSGIApplication([
    webapp2.Route(r'/login', LoginHandler, name='login', schemes=[app_scheme]),
    webapp2.Route(r'/profile', ProfileHandler, name='profile', schemes=[app_scheme]),
    webapp2.Route(r'/', HomeHandler)
], debug=True)

我已将此应用程序的代码上传到我的AE-BaseApp GitHub,请随时下载并在您的应用程序中使用它。该代码已获得 Apache License 2.0 的许可。

于 2012-06-01T05:47:36.417 回答