私はFlask-HTTPAuthを使用して、基本認証を使用して2層認証システムを作成しようとしています。私のアプリケーションは2つのルートを持っています。/
にはログインしているユーザーがアクセスでき、adminルートは/admin
にアクセスできます。チェーンデコレータによるFlask-HTTPAuthを使用して特権ユーザーを作成する---コンテキストを失う?
次のようにだから私は(dbopsがデータベースに話を扱うだけの名前空間である場合)、コードの関連する部分と、デコレータを連鎖することによって、これを実施することを決定:
@auth.verify_password
def verify_pw(lastname, password):
ln = lastname.lower()
if ln in dbops.list_users():
hashed_pw = dbops.find_hashed_password(ln)
return bcrypt.checkpw(password.encode('utf8'), hashed_pw.encode('utf8'))
return False
def must_be_admin(f):
@wraps(f)
def wrapper(*args, **kwargs):
if dbops.is_admin(auth.username()):
return f(*args, **kwargs)
return "Not authorized."
return wrapper
@core.route("/")
@auth.login_required
def dataentry():
return render_template("dataentry.html")
@core.route("/admin")
@must_be_admin
@auth.login_required
def admin():
return render_template("admin.html")
これは正常に動作していれば管理者ユーザーとしてログインしようとする人は、まず/
ルートにアクセスします。ユーザー名とパスワードの入力を求めるメッセージが表示され、管理者ユーザーは/admin
に行き、ログインした管理タスクを実行できます。
ただし、管理者が初めて/admin
にアクセスすると、ログインプロンプトが表示されません。ただスローして、デバッガを突き刺した後、私はauth.username()
が空の文字列を返すと判断しました。だから、私の推測では、何らかの理由で内部のデコレータが適用されていないため、ログインプロンプトが表示されません。
ここで何が起こっているのでしょうか?
私の最初の仮説は、管理デコレータの内部機能がis_admin
チェックの後まで呼び出されていないため、これは簡単なバグであるということでした。次のようにだから私は、私は、関数を呼び出す---ので、おそらくチェックする前に--- auth.username()
を利用可能にすることを解決しようとした:
def must_be_admin(f):
@wraps(f)
def wrapper(*args, **kwargs):
dummy_to_get_username = f(*args, **kwargs)
if dbops.is_admin(auth.username()):
return dummy_to_get_username
return "Not authorized."
return wrapper
をしかし、それはちょうど同じ行動を起こしました。
私はthis prior SOから、ライブラリ作成者からこれを行うには、2つの別々のFlask-HTTPAuthオブジェクトを作成することをお勧めします。それは私がすることができます、問題ありません。しかし、デコレータがどのように動作しているかについての私の精神モデルは失敗しているので、私は作業したい機能を得ることとは無関係にこの問題を解決したいと思います...
ありがとうございました!すべてのフラスコの質問でここで活発に活動していることは素晴らしいことです。 –