2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

個人的備忘録:夏のハッカソンで実装した Flask のログイン機能を紐解きながらアウトプットしてみた

Last updated at Posted at 2025-02-08

はじめに

前回の記事では、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 リクエストで emailpassword を受け取る。
  • 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)にリダイレクトするが、
    セッションを削除する処理がないため、実際にはログアウトできていない。

ログアウトを実装する場合:

  1. session.pop('uid', None) を実行してセッションを削除。
  2. redirect('/login') でログイン画面にリダイレクト。
@app.route('/logout')
def logout():
    session.pop('uid', None)  # セッションからユーザーIDを削除
    return redirect('/login')

こうすることで、session['uid'] が削除され、再度アクセスした際にログインが必要になる。

まとめ

お読みいただきありがとうございました。今回の記事を通じて、過去に実装した内容を振り返る良い機会となりました。

今後も、以前書いたコードを見直しながら、どのような仕組みだったのかを整理し、体系的にアウトプットしていきたいと考えています。

本記事は個人の備忘録としてまとめたものですが、温かく見守っていただけると嬉しいです。

2
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?