はじめに
前回の記事では、Flask を使った認証機能の基本について紹介しました。
今回は、その続きとして 実際にログイン処理を実装する方法 を詳しく解説します。
Flask の session
を活用し、ログインフォームの作成から認証、セッション管理、ログアウトまでの流れ を見ていきます。
前回の記事の続きです。
書こうと思ったきっかけ
Flask でログイン機能を実装する際、認証処理の流れを**「どう設計するべきか」「どのように実装するのか」** について迷うことが多いと感じました。
特に、セッション管理やパスワードの取り扱い(ハッシュ化など) には注意が必要です。
この記事では、以下のポイントを押さえながら、実際のコードとともに解説 していきます。
- ログインフォームの作成
- ユーザー認証(データベースとの照合)
- セッションを活用したログイン状態の管理
- ログアウト処理の実装
実際に実装してみた(Flask)
受講中の IT スクールのハッカソンで作成したチャットアプリのリポジトリを共有します。必要に応じて参考にしてみてください。
当時はまだコードの書き方が洗練されておらず、改善の余地が多い部分もありますが、温かい目で見守っていただければ幸いです。
1. ログインフォームの表示
@app.route('/login')
def login():
return render_template('registration/login.html')
GET /login
にアクセスすると、ログインページ(registration/login.html
)が表示される。
2. ログイン処理
@app.route('/login', methods=['POST'])
def userLogin():
email = request.form.get('email')
password = request.form.get('password')
if not email or not password: # 空のフォームチェック
flash('メールアドレスまたはパスワードが入力されていません')
else:
user = dbConnect.getUser(email) # メールアドレスを元にユーザー情報を検索
if user is None:
flash('このユーザーは存在しません')
else:
if not check_password_hash(user["password"], password): # ハッシュ化されたパスワードと照合
flash('パスワードが間違っています!')
else:
session['uid'] = user["uid"]
return redirect('/')
return redirect('/login')
POST
リクエストでemail
とpassword
を受け取る。-
dbConnect.getUser(email)
でデータベースからユーザー情報を取得。 - 入力された
password
がデータベースのuser["password"]
と一致するか確認。
一致した場合:
-
session['uid'] = user["uid"]
でセッションにユーザーのuid
を保存。(ここでログインが完了!) -
redirect('/')
でホーム画面にリダイレクト。
一致しない場合:
-
flash('パスワードが間違っています!')
でエラーを表示し、再度/login
にリダイレクト。
3. ログイン状態の確認
@app.route('/')
def home():
uid = session.get("uid")
if uid is None:
return redirect('/login')
else:
channels = dbConnect.getChatAll()
channels = channels[::-1]
user = dbConnect.getUserByUid(uid)
return render_template('home.html', channels=channels, uid=uid, user=user)
-
session.get("uid")
でログイン状態を確認。 -
ログインしていない (
uid is None
) 場合 は/login
にリダイレクト。 -
ログインしている場合 は
uid
をもとにユーザー情報を取得して、ホーム画面を表示。
4. ログインユーザー名の取得
@app.route('/get_logged_in_user', methods=['GET'])
def get_logged_in_user():
logged_in_user_id = session.get('uid')
if not logged_in_user_id:
return jsonify({"message": "ログインしていません"}), 401
logged_in_username = dbConnect.getUsernameByUid(logged_in_user_id)
if not logged_in_username:
return jsonify({"message": "ユーザー情報の取得に失敗しました"}), 500
return jsonify({"username": logged_in_username}), 200
- API エンドポイント
/get_logged_in_user
でログイン中のユーザー名を取得。 -
session.get('uid')
でログイン中のユーザー ID を取得し、データベースからusername
を検索。
5. ログアウト
@app.route('/logout')
def logout():
return render_template('registration/login.html')
-
/logout
にアクセスすると、ログイン画面(registration/login.html
)にリダイレクトするが、
セッションを削除する処理がないため、実際にはログアウトできていない。
ログアウトを実装する場合:
-
session.pop('uid', None)
を実行してセッションを削除。 -
redirect('/login')
でログイン画面にリダイレクト。
@app.route('/logout')
def logout():
session.pop('uid', None) # セッションからユーザーIDを削除
return redirect('/login')
こうすることで、session['uid']
が削除され、再度アクセスした際にログインが必要になる。
まとめ
お読みいただきありがとうございました。今回の記事を通じて、過去に実装した内容を振り返る良い機会となりました。
今後も、以前書いたコードを見直しながら、どのような仕組みだったのかを整理し、体系的にアウトプットしていきたいと考えています。
本記事は個人の備忘録としてまとめたものですが、温かく見守っていただけると嬉しいです。