2012-05-29 17 views
7

原始的問題如何使用WSGI從HTTP重新路由用戶到HTTPS


的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一樣。這太像我喜歡的黑客了。我真的不喜歡我的代碼中的硬編碼網址。更不用說它是2個登錄請求並不是什麼大問題,但也可能有其他的例子,最終花費太多。

注意1:如果您正在查看此解決方案,請注意,使用HTTPS方案還意味着您將無法使用開發控制檯而不刪除SCHEME或配置您爲dev設置的變量。

注2:我是能夠得到一個程序化的方式服務HTTPS而不是HTTP。我在下面的評論正確的軌道上,但它需要一個論點。

webapp2.uri_for('login', _scheme='https')
這會給你正確的https://someapp.appspot.com/login url。不幸的是,我不關心如何處理用戶在不使用https的情況下將地址欄輸入到地址欄中的主要問題,並且在我使用上面的黑客攻擊時收到錯誤。所以我仍然在尋找WSGI的方式來將收入請求路由到HTPPS。

編輯:添加註1和澄清的標題,我認爲這是顯而易見的是,我使用WSGI從源而不是CGI。

+0

雖然這是使用'webapp2.uri_for('login')的一個側面問題'也不會生成https作爲URL。因此,我仍然試圖解決所有問題。如果用戶沒有在HTTP中啓動https App Engine插件,並且在/ login上發生錯誤,因爲它仍然是http,除非我硬編碼鏈接或使用我的上面的黑客。 –

+0

如何做一個字符串替換用https替換http?這不是最好的解決方案,但至少你不需要對整個URL進行硬編碼 – Dhara

+0

無論你接受還是不接受,請將你的問題的答案作爲答案發布(你可以接受你自己的答案,特別是而不是錯誤的答案,正如你在下面的評論中所建議的那樣)。 – Bruno

回答

1

這是我在測試這個問題時使用的工作代碼。

注:開發Web服務器(在本文寫作v1.6.5的)不支持HTTPS所以你的WSGI路線將需要刪除在開發環境中工作的方案。您可以在部署之前將它們添加回來,或者創建一個變量來設置檢查環境的方案,如下所示。

您可以通過將app.yaml定義爲:
應用程序來讓App Engine Python重新路由該請求。YAML

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處理程序爲正常,如:

main.py

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許可證2.0。

8

設置app.yaml中的網址,而不是代碼。見https://developers.google.com/appengine/docs/python/config/appconfig#Secure_URLs

例如:

handlers: 

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

這將HTTP重定向到HTTPS。

+0

不幸的是,這是一種CGI方法,與使用[線程安全](https://developers.google.com/appengine/docs/python/config/appconfig#Using_Concurrent_Requests)不兼容,或者我將如何做到這一點開始。如果有的話,我正在尋找WSGI的方法。 –

+1

在那篇文檔中,它說或暗示'secure'與'threadsafe'不兼容?它不,它不是。 –

+0

@ Daniel-Roseman I [quote](https://developers.google.com/appengine/docs/python/python27/using27#Configuring_WSGI_Script_Handlers)「警告!如果您計劃使用併發請求,則必須使用WSGI處理程序。」如果您在聲明線程安全時將CGI處理程序放在app.yaml中,則會出現以下錯誤。 '加載應用程序配置時發生致命錯誤:' '無效對象:' '無法使用CGI處理程序啓用線程安全:main.py' –

相關問題