Flask
認可と認証
サーチ…
フラスコログイン拡張機能を使用する
認証システムを実装する簡単な方法の1つは、 フラスコログイン拡張を使用することです。このプロジェクトのウェブサイトには、詳細かつよく書かれたクイックスタートが含まれています。このクイックスタートは、この例では短いバージョンです。
一般的なアイデア
この拡張機能は、次の目的で使用される一連の関数を公開します。
- ユーザーのログイン
- ユーザーをログアウトする
- ユーザーがログインしているかどうかを確認し、どのユーザーがそのユーザーであるかを調べる
それが何をしないのか、自分で何をしなければならないのか:
- ユーザーをデータベースに格納する方法を提供していません
- ユーザーの資格情報(ユーザー名とパスワードなど)を確認する方法はありません。
下には、すべての作業を行うために必要な最小限の手順があります。
auth関連のコードを別のモジュールやパッケージに置くことをお勧めします。たとえば、 auth.py
です。そうすれば、必要なクラス、オブジェクト、またはカスタム関数を個別に作成できます。
LoginManager
作成
この拡張機能は、 Flask
アプリケーションオブジェクトに登録する必要があるLoginManager
クラスを使用します。
from flask_login import LoginManager
login_manager = LoginManager()
login_manager.init_app(app) # app is a Flask object
前述のように、 LoginManager
は、例えば、別々のファイルまたはパッケージ内のグローバル変数とすることができます。その後、 Flask
オブジェクトが作成されたファイルまたはアプリケーションファクトリ関数にインポートされ、初期化されます。
ユーザーの読み込みに使用されるコールバックを指定する
通常、ユーザーはデータベースからロードされます。コールバックは、指定されたIDに対応するユーザーを表すオブジェクトを戻す必要があります。 IDが有効でない場合は、 None
を返します。
@login_manager.user_loader
def load_user(user_id):
return User.get(user_id) # Fetch the user from the database
これはLoginManager
作成の直下で行うことができます。
あなたのユーザを表すクラス
前述のように、 user_loader
コールバックは、ユーザを表すオブジェクトを返す必要があります。それはどういう意味ですか?そのオブジェクトは、たとえば、データベースに格納されたユーザーオブジェクトのまわりのラッパー、または単にデータベースのモデルに直接アクセスできます。そのオブジェクトは、以下のメソッドとプロパティを実装する必要があります。つまり、コールバックがデータベースモデルを返す場合は、前述のプロパティとメソッドをモデルに追加する必要があります。
is_authenticated
このプロパティは、ユーザーが認証された場合、つまり有効な資格情報を提供している場合に
True
を返します。user_loader
コールバックによって返されたユーザーを表すオブジェクトがそのメソッドに対してTrue
を返すようにするuser_loader
ます。is_active
これがアクティブなユーザーである場合、このプロパティはTrueを返します。認証されているだけでなく、アカウントがアクティブになっているか、中断されていないか、またはアプリケーションがアカウントを拒否している状態になっています。無効なアカウントはログインできません。このようなメカニズムがない場合は、このメソッドから
True
を返しTrue
。is_anonymous
これが匿名ユーザーの場合、このプロパティはTrueを返す必要があります。つまり、
user_loader
コールバックによって返されたユーザーオブジェクトはTrue
を返す必要がありTrue
。get_id()
このメソッドは、このユーザーを一意に識別するユニコードを返さなければならず、
user_loader
コールバックからユーザーをロードするために使用できます。これはユニコードでなければならないことに注意してください。IDがネイティブでintまたはその他のタイプの場合は、ユニコードに変換する必要があります。user_loader
コールバックがデータベースからオブジェクトを返す場合、このメソッドはおそらくこの特定のユーザーのデータベースIDを返します。同じIDは、もちろん、user_loader
同じユーザを返すようにuser_loader
コールバックを引き起こすはずです。
実際に自分自身で簡単にしたい場合は、 user_loader
コールバック(おそらくデータベースモデル)によって返されたオブジェクトのUserMixin
から継承することができます。このミックスインでは、デフォルトでこれらのメソッドとプロパティがどのように実装されているかを見ることができます 。
ユーザーのログイン
この拡張機能により、ユーザーが入力したユーザー名とパスワードの検証が行われます。実際には、ユーザー名とパスワードの組み合わせやその他のメカニズムを使用するかどうかは問題になりません。これはユーザー名とパスワードを使用してユーザーを記録する例です。
@app.route('/login', methods=['GET', 'POST'])
def login():
# Here we use a class of some kind to represent and validate our
# client-side form data. For example, WTForms is a library that will
# handle this for us, and we use a custom LoginForm to validate.
form = LoginForm()
if form.validate_on_submit():
# Login and validate the user.
# user should be an instance of your `User` class
login_user(user)
flask.flash('Logged in successfully.')
next = flask.request.args.get('next')
# is_safe_url should check if the url is safe for redirects.
# See http://flask.pocoo.org/snippets/62/ for an example.
if not is_safe_url(next):
return flask.abort(400)
return flask.redirect(next or flask.url_for('index'))
return flask.render_template('login.html', form=form)
一般的に、ログインユーザーはlogin_userを呼び出して、 先ほど説明したユーザーを表すオブジェクトのインスタンスを渡します。これは、通常、データベースからユーザを取得して認証情報を検証した後に発生しますが、この例ではユーザオブジェクトが魔法のように表示されます。
私はユーザーにログインしました、今は何ですか?
user_loader
コールバックによって返されるオブジェクトは、複数の方法でアクセスできます。
テンプレートの場合:
この拡張機能は、テンプレートコンテキストプロセッサを使用して、その名前を
current_user
という名前で自動的に挿入します。その動作を無効にしてカスタムプロセッサを使用するには、LoginManager
コンストラクタでadd_context_processor=False
を設定します。{% if current_user.is_authenticated %} Hi {{ current_user.name }}! {% endif %}
Pythonコードの場合:
この拡張機能は、
current_user
という要求バインドされたオブジェクトを提供しcurrent_user
。from flask_login import current_user @app.route("/hello") def hello(): # Assuming that there is a name property on your user object # returned by the callback if current_user.is_authenticated: return 'Hello %s!' % current_user.name else: return 'You are not logged in!'
デコレータを使用して素早くアクセスを制限する
login_required
デコレータを使用すると、アクセスを素早く制限することができます。from flask_login import login_required @app.route("/settings") @login_required def settings(): pass
ユーザーのログアウト
ユーザーはlogout_user()
呼び出すことでログアウトできます。ユーザーがログインしていなくても@login_required
デコレータが省略されている可能性が高い場合でも、そうするのが安全だと思われます。
@app.route("/logout")
@login_required
def logout():
logout_user()
return redirect(somewhere)
ユーザーがログインしていない状態でcurrent_user
オブジェクトにアクセスするとどうなりますか?
defolultによってAnonymousUserMixinが返されます:
-
is_active
およびis_authenticated
はFalse
-
is_anonymous
はTrue
-
get_id()
はNone
返します。
匿名ユーザーに別のオブジェクトを使用するには、 LoginManager
匿名ユーザーを作成する呼び出し可能なクラスまたはファクトリ関数を提供します。
login_manager.anonymous_user = MyAnonymousUser
次は何?
以上で、拡張機能の基本的な説明は終わりです。設定と追加オプションの詳細については、公式ガイドを読むことを強くお勧めします 。
ログインセッションのタイムアウト
特定の時間の後にセッションでログアウトするのが良い習慣で、あなたはFlask-Loginでそれを達成することができます。
from flask import Flask, session
from datetime import timedelta
from flask_login import LoginManager, login_require, login_user, logout_user
# Create Flask application
app = Flask(__name__)
# Define Flask-login configuration
login_mgr = LoginManager(app)
login_mgr.login_view = 'login'
login_mgr.refresh_view = 'relogin'
login_mgr.needs_refresh_message = (u"Session timedout, please re-login")
login_mgr.needs_refresh_message_category = "info"
@app.before_request
def before_request():
session.permanent = True
app.permanent_session_lifetime = timedelta(minutes=5)
デフォルトのセッションの有効期間は31日です。タイムアウトが発生した場合にログインの更新表示を指定する必要があります。
app.permanent_session_lifetime = timedelta(minutes=5)
上の行は、ユーザーに5分ごとに再ログインを強制します。