
前の記事では、Jinja2テンプレートエンジンを使用して、バックエンドのPythonロジックからフロントエンドのHTMLコードを分離し、プロジェクト構造をより明確にしました。
現在のフォーラムでは誰でも匿名で投稿できるため、コミュニティの運営方法としては適切ではありません。フォーラムはユーザーを中心に構築されるべきです。各ユーザーには独自のID、独自の投稿、返信があります。
そこで、この記事では、ユーザー登録、ログイン、ログアウト機能を含む完全なユーザーシステムをフォーラムに追加します。
ステップ1:依存関係のインストール
パスワード暗号化を処理するライブラリが必要です。ユーザーのパスワードは、極めて危険であるため、プレーンテキストで保存することはできません。ここではpasslibとpbkdf2_sha256アルゴリズムを使用します。
次のコマンドを実行します。
ステップ2:データベースモデルの更新
ユーザー情報を保存するための新しいテーブルが必要であり、各投稿の作成者を記録するためにpostsテーブルをusersテーブルに関連付ける必要があります。
models.pyファイルを開き、以下の変更を加えます。
models.py(更新版)
ここでは2つのことを行いました。
Userモデルの作成:id、一意のusername、hashed_passwordフィールドを含むusersテーブルを定義します。
PostとUserの関連付け:Postモデルに、usersテーブルのidを指す外部キーとしてowner_idフィールドを追加しました。- SQLAlchemyの
relationshipを使用して、PostとUserの間に双方向の関連付けを確立しました。これで、post.ownerを通じて投稿の作成者にアクセスでき、user.postsを通じてユーザーのすべての投稿にアクセスすることもできます。
これらのモデルを適用する前に、データベースを手動で更新する必要があります。usersテーブルを作成し、postsテーブルを変更する必要があります。
対応するSQLステートメントは次のとおりです。
Leapcellを使用してデータベースを作成した場合、
そのWebベースの操作パネルでこれらのSQLステートメントを直接実行できます。
ステップ3:パスワードの処理
新しいファイルauth.pyを作成し、パスワードハッシュ化および検証用の関数を記述して、パスワードを安全に処理します。
auth.py
verify_password:ユーザーが入力したプレーンテキストパスワードとデータベースに保存されているハッシュ化されたパスワードを比較して、一致するかどうかを確認します。get_password_hash:プレーンテキストパスワードをハッシュ値に変換して、データベースに保存できるようにします。
ステップ4:ユーザー登録およびログインページの作成
posts.htmlと同様に、templatesフォルダ内にregister.htmlとlogin.htmlという2つの新しいHTMLファイルを作成します。
templates/register.html
templates/login.html
ステップ5:認証関連のAPIルートの実装
main.pyをリファクタリングして、登録、ログイン、ログアウト、および現在のユーザー状態管理機能を追加します。これは比較的大きな更新です。
main.py(最終完全版)
このファイルは主にこれらの変更を行いました。
get_current_user関数の追加:この関数は、リクエスト内のforum_userCookieを読み取って現在のユーザーを識別します。後続のルートでは、Depends(get_current_user)を通じてログイン中のユーザー情報を直接取得できます。- ユーザー登録およびログイン関連ルートの追加
- 登録(
/register):GETリクエストは登録フォームを表示し、POSTリクエストはフォーム送信を処理します。ユーザー名が既に存在するかどうかを確認し、パスワードをハッシュ化してデータベースに保存します。 - ログイン(
/login):GETリクエストはログインフォームを表示します。POSTリクエストは、ユーザー名とパスワードを検証します。成功した場合、レスポンスにforum_userという名前のCookieを設定し、ユーザー名を値として設定します。これはシンプルなセッション実装です。 - ログアウト(
/logout):forum_userCookieをクリアし、ホームページにリダイレクトします。
- 登録(
- ルート保護:
create_postルートは、get_current_userに依存するようになりました。ユーザーがログインしていない場合、ログインページにリダイレクトされます。投稿時、投稿のowner_idは自動的に現在ログインしているユーザーのIDに設定されます。 - ビューの更新:
/postsなどのルートは、現在のユーザー情報を取得し、テンプレートに渡して、ページにログイン状態を表示できるようにします。
ステップ6:ホームページテンプレートを更新してユーザー状態を表示する
最後に、templates/posts.htmlを修正して、ユーザーのログイン状態に基づいて異なるコンテンツを表示できるようにします。
templates/posts.html(更新版)
テンプレートは主にこれらの変更を行いました。
- 上部のナビゲーションは、ログイン状態を判断するために
{% if current_user %}を使用します。ユーザーがログインしている場合、ウェルカムメッセージと「Logout」リンクが表示されます。それ以外の場合は、「Login」と「Register」リンクが表示されます。 - 新しい投稿用のフォームは、ログイン中のユーザーのみが表示できるように制限されています。
- 各投稿の下部に、
{{ post.owner.username }}を通じて作成者のユーザー名が表示されます。
実行と検証
結果を確認する時です!uvicornサーバーを再起動します。
http://127.0.0.1:8000にアクセスします。ホームページの右上隅に「Login」と「Register」リンクが表示され、ページに投稿を作成するエントリはありません。
新しいユーザーを登録し、ログインしてみてください。ログイン後、投稿フォームが表示され、ページの上部にユーザー名が表示されます。
投稿を送信すると、その作成者は正しくあなたのユーザー名として表示されます。
まとめ
この記事を通じて、フォーラムのユーザーシステムを構築しました。これで、誰もが登録、ログイン、そして自分の投稿を公開できます。
投稿にユーザーが紐づいた後、次のことを検討できます。もしユーザーが自分で公開した投稿の内容を変更したい場合はどうなるでしょうか?
次の記事では、現在のユーザーシステムに基づいた新しい機能、つまりユーザーが既に作成した投稿を編集できるようにする機能を実装します。
Xでフォローする:@LeapcellJapan
関連記事:
