今回はFlaskのWebアプリケーションにログイン機能を実装します。
前提
今回は最もシンプルな方法でログイン機能を実装します。SSO等は一切考慮していません。また、DBとの接続もせず、あくまでFlask内のログイン機能の実装にフォーカスを当てます。
フォルダ構成
フォルダ構成は以下の通りです。画面はログイン画面と、ログイン後の画面の2つです。
..
L templates
| L dashbord.html
| L login.html
L main.py
HTMLファイル
以下HTMLの中身です。
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
</head>
<body>
{% if error %}
<p>{{ error }}</p>
{% endif %}
<form method="post" action="/login">
<label>Username:</label>
<input type="text" name="username" required>
<br>
<label>Password:</label>
<input type="password" name="password" required>
<br>
<input type="submit" value="Login">
</form>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Dashboard</title>
</head>
<body>
<h1>Welcome, {{ session["username"] }}!</h1>
<p>This is your dashboard.</p>
<!-- ログアウトボタンを追加 -->
<form action="/logout" method="post">
<input type="submit" value="Logout">
</form>
</body>
</html>
Flaskで実装
パッケージのインストール
今回必要なのは、Flaskの以下パッケージです。
from flask import Flask, render_template, request, redirect, url_for, session
ユーザ情報の定義
今回ログインできるユーザ情報はプログラムに辞書形式で定義します。一般的にアカウント情報はDB等で管理します。DBから取得する場合は、以下の部分をDBで取得するように変更してください。
# シンプルなユーザーデータの辞書
users = {
'user1': {'username': 'user1', 'password': 'password1'},
'user2': {'username': 'user2', 'password': 'password2'}
}
ログイン画面について
まず、http://127.0.0.1:5000/(ローカルの場合)にアクセスすると、login.htmlを表示するようにします。
@app.route("/")
def main_page():
return render_template('login.html')
ログイン画面は以下のようなものです。
ログイン機能の実装
ログインはlogin()関数にて実装します。login()は、ログイン画面が”Login”ボタンを押すことで呼ばれます。
関数は以下内容とします。
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
# 画面で入力された情報を取得
username = request.form['username']
password = request.form['password']
# ログイン可否を判定
if username in users and users[username]['password'] == password:
session['username'] = username
# ログイン成功でdashbord.htmlを返す
return redirect(url_for('dashboard'))
else:
return render_template('login.html', error='Invalid credentials')
# GETの場合はログイン画面へ戻す
return render_template('login.html')
GET、POSTどちらでも受け付けますが、処理の中でGETの場合はログイン画面に再び戻しています。なので、実質的にPOSTでログインすることになります。
login.htmlからは画面で入力したusernameとpasswordが渡されます。それらはrequest.formから取り出します。
受け取った情報が登録されている情報と一致する場合は、セッションにユーザ情報を格納し、dashbord.htmlを返します。
dashbord画面は以下のような画面です。
直接dashbord.htmlにアクセスしようとした場合について
Login画面からはdashbord.htmlに繋がるかの制御を実施していますが、URLで直接http://127.0.0.1:5000/dashboardが実行された場合の制御もしておく必要があります。
具体的には、セッション情報に”username”が存在するかで判定します。これは、ログイン成功時にセッションに追加されるものです。
@app.route('/dashboard')
def dashboard():
if 'username' in session:
return render_template('dashbord.html')
else:
return redirect(url_for('login'))
なお、実際のセキュリティ要件に合わせてこういったケースでさらに厳密な制御が求められる場合もあります。今回はあくまで最低限のログイン機能なので、状況に応じて認証方法を変更してください。
ログアウト機能の実装
dashbord.htmlには、Logoutボタンがついています。ボタンを押すと、ログアウトできるようにします。
@app.route('/logout', methods=['GET', 'POST'])
def logout():
session.pop('username', None)
return redirect(url_for('login'))
ログアウト方法として、セッションからusernameを削除しています。
そして、ログイン画面に遷移します。
コード全体
最後にmain.pyのコード全体です。
from flask import Flask, render_template, request, redirect, url_for, session
app = Flask(__name__)
# シンプルなユーザーデータの辞書(適宜DB接続等実施してください)
users = {
'user1': {'username': 'user1', 'password': 'password1'},
'user2': {'username': 'user2', 'password': 'password2'}
}
@app.route("/")
def main_page():
return render_template('login.html')
#ログイン処理
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
# 画面で入力された情報を取得
username = request.form['username']
password = request.form['password']
# ログイン可否を判定
if username in users and users[username]['password'] == password:
session['username'] = username
# ログイン成功でdashbord.htmlを返す
return redirect(url_for('dashboard'))
else:
return render_template('login.html', error='Invalid credentials')
# GETの場合はログイン画面へ戻す
return render_template('login.html')
#URL直接参照の場合
@app.route('/dashboard')
def dashboard():
# ログインしている場合はdashbord.htmlへ
if 'username' in session:
return render_template('dashbord.html')
else:
return redirect(url_for('login'))
#ログアウト機能
@app.route('/logout', methods=['GET', 'POST'])
def logout():
session.pop('username', None)
return redirect(url_for('login'))
if __name__ == "__main__":
app.run()
まとめ
Flaskでログイン機能を実装する方法を紹介しました。アプリケーションによってセキュリティ要件は変わってくるので、必要に応じて認証方法等は変更してください。Flaskでの構成については、本記事が参考になれば幸いです。
ではでは👋