私はFlaskを使用しようとしており、Flask-Loginという拡張をFlaskアプリケーションでユーザ認証を実装しようとしています。目標は、データベースからユーザーアカウント情報を取得してユーザーにログインすることですが、私は立ち往生しています。しかし、私はFlask-Loginの動作の特定の部分に絞り込んだ。Flaskログインでuser_loaderコールバックを実装する方法
Flask-Login documentationによると、私はuser_loader "コールバック"関数を作成する必要があります。この関数の実際の目的と実装により、私は数日後に混乱しました。
user_loaderコールバックを提供する必要があります。このコールバックは、 を使用して、セッションに格納されているユーザーIDからユーザーオブジェクトをリロードします。 は、ユーザーのUnicode IDを取得し、対応する ユーザーオブジェクトを返す必要があります。たとえば:
@login_manager.user_loader def load_user(userid): return User.get(userid)
は今、私は、ユーザーが、フォームに名前とパスワードを入力し、データベースに対してチェックして、ユーザーにログインすると言います。データベースの内容はうまく動作し、問題はありません。
この 'コールバック'関数は、ユーザーID#を渡して、Userオブジェクト(その内容をデータベースからロードしています)を返します。しかし、ユーザーIDはすべて同じ場所から引き出されているため、確認/実行する必要があるものは実際には得られません。私はコールバックを動作させるために「並べ替え」をすることはできますが、それは面倒で/ハッキリしているように見え、ブラウザが要求するすべての単一リソースでデータベースにヒットします。私は実際にすべてのページリフレッシュでfavicon.icoをダウンロードするために自分のデータベースをチェックしたくないのですが、フラスコログインはこれを強制しているようです。
データベースをもう一度チェックしないと、この関数からUserオブジェクトを返す方法がありません。 Userオブジェクト/クラスは、ログインのためのフラスコルートで作成され、コールバックの範囲外です。
私が理解できないことは、毎回データベースにヒットすることなく、このコールバック関数にUserオブジェクトを渡す方法です。あるいは、これをもっと効果的な方法でやり遂げる方法を見つけ出す。私は何か基本的なものを見逃しているに違いないが、私は数日前からそれを見つめていて、あらゆる種類の機能と方法を投げかけている。
私のテストコードに関連するスニペットを示します。 Userクラス:
class UserClass(UserMixin):
def __init__(self, name, id, active=True):
self.name = name
self.id = id
self.active = active
def is_active(self):
return self.active
私はフラスコ-ログインのuser_loaderコールバック関数へのユーザーオブジェクトを返すために作られた機能:
def check_db(userid):
# query database (again), just so we can pass an object to the callback
db_check = users_collection.find_one({ 'userid' : userid })
UserObject = UserClass(db_check['username'], userid, active=True)
if userObject.id == userid:
return UserObject
else:
return None
「コールバック」、私は完全に理解していない(返さなければなりませんデータベースから引っ張った後、作成されたユーザーオブジェクト、):
@login_manager.user_loader
def load_user(id):
return check_db(id)
ログインルート:
@app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "POST" and "username" in request.form:
username = request.form["username"]
# check MongoDB for the existence of the entered username
db_result = users_collection.find_one({ 'username' : username })
result_id = int(db_result['userid'])
# create User object/instance
User = UserClass(db_result['username'], result_id, active=True)
# if username entered matches database, log user in
if username == db_result['username']:
# log user in,
login_user(User)
return url_for("index"))
else:
flash("Invalid username.")
else:
flash(u"Invalid login.")
return render_template("login.html")
私のコード 'kinda'は動作しますが、ログインとログアウトができますが、私は、異なる名前空間/スコープのコールバック関数にUserオブジェクトを提供する必要があるため、残りのログインアクションがどこから行われるかを示します。私はそれがすべて間違っているとはかなり確信していますが、私はどのように把握できません。
フラスコログインdoes it this wayで提供されているサンプルコードですが、これはDBをチェックする必要があるデータベースのような現実のシナリオではなく、グローバルハードコードされた辞書からUserオブジェクトを引き出しているためですの後にというユーザーオブジェクトが作成され、ユーザーはログイン資格情報を入力します。フラスコログインを使ってデータベースを使用することを示す他のサンプルコードも見つからないようです。
ここには何が欠けていますか?
どのように奇妙です。あなたのログイン()はパスワードを確認しない。 – Houman
@hoomanこれはあくまで例です。 –