App Engine Dev Server をセットアップして、他のユーザーがプレビューできるようにしたいと考えています。
その前に本当にやりたいことは、そのサイトから提供されるすべての URL に対して HTTP 認証を有効にすることです。その段階を経ずに、誰もサービスにアクセスしたくありません。もちろん、開発中のアプリに独自の HTTP 認証を組み込むこともできますが、それは完全な解決策ではありません。アプリの展開時にその機能は必要ないからです。
それを解決する良い方法はありますか?
App Engine Dev Server をセットアップして、他のユーザーがプレビューできるようにしたいと考えています。
その前に本当にやりたいことは、そのサイトから提供されるすべての URL に対して HTTP 認証を有効にすることです。その段階を経ずに、誰もサービスにアクセスしたくありません。もちろん、開発中のアプリに独自の HTTP 認証を組み込むこともできますが、それは完全な解決策ではありません。アプリの展開時にその機能は必要ないからです。
それを解決する良い方法はありますか?
dev_appserver をパブリックにアクセス可能にしないでください。そのために設計されておらず、安全ではありません。問題を 1 つだけ挙げると、どの訪問者も yourhost/_ah/admin/ にアクセスしてデータストアをいじることができ、lost-theory による認証の提案はそれを防ぎません。
絶対にこれを行う必要がある場合は、Apache または別の Web サーバーをリバース プロキシとして設定し、認証を実装して /_ah URL へのアクセスをブロックします。ただし、それを App Engine にデプロイするという Peter の提案は、はるかに優れています。
アプリを appengine サーバーにデプロイしますが、本番環境で最終的に使用するアプリ ID とは異なるアプリ ID を使用します。そうすれば、追加の認証メカニズムを開発する必要がなく、開発アプリ サーバーが複数のユーザーに相当する負荷をどれだけうまく処理できるかを心配する必要もありません。
ここに私が思いついたかなり堅実な実装があります
検索した結果、オンラインで GAE の BasicAuth のずさんな/不完全な実装が大量に見つかりました。結果、自分で書くことになりました。これは、これまでに思いついた最良/最も簡単なアプローチです。
リクエストハンドラーをできるだけ薄く保つことは「良い習慣」だと思います。ハンドラー自体のボイラープレートとコピーパスタを削減するために、認証をデコレーターとして実装することにしました。これを使用するには、デコレーターをハンドラーの get/post/put/delete メソッドにアタッチするだけです。
例えば:
from decorators import basic_auth
class Handler(webapp2.RequestHandler):
@basic_auth
def get(self):
# load your page here
次に、デコレータを decorators.py に追加します。
import base64
import os
from webapp2_extras import security
import yaml
def basic_auth(func):
def callf(webappRequest, *args, **kwargs):
# Parse the header to extract a user/password combo.
auth_header = webappRequest.request.headers.get('Authorization')
# if the auth header is missing popup a login dialog
if auth_header == None:
__basic_login(webappRequest)
else:
(username, password) = base64.b64decode(auth_header.split(' ')[1]).split(':')
if(__basic_lookup(username) == __basic_hash(password)):
return func(webappRequest, *args, **kwargs)
else:
__basic_login(webappRequest)
return callf
def __basic_login(webappRequest):
webappRequest.response.set_status(401, message="Authorization Required")
webappRequest.response.headers['WWW-Authenticate'] = 'Basic realm="Secure Area"'
def __basic_lookup(username):
accounts_file = os.getcwd() + os.sep + 'app' + os.sep + 'accounts.yaml'
stream = file(accounts_file, 'r')
for account in yaml.load(stream):
if account['username'] == username:
return account['password']
def __basic_hash(password):
return security.hash_password(password, method='sha1')
注: ここでは、「decorators」モジュールの外では表示されてはならない関数に対して、接頭辞付きの二重アンダースコアが使用されています。
この場合、ログイン試行が失敗すると、別のログイン ダイアログがポップアップ表示されます。別の accounts.yaml ファイルに保存されているパスワードを使用して認証を行っており、パスワードは SHA1 ハッシュ形式で保存されています。
コードは簡単にカスタマイズできるように記述されています。
Java または Python を使用していますか?
Python を使用している場合は、既存の WSGI ミドルウェアを使用して HTTP 基本認証を処理できます。以下にいくつかのオプションを示します。