本日の目的・ゴール
目的
ユーザー登録のコードの流れを理解する。
(ユーザー登録・ログイン・確認まで)
ゴール
ユーザーのname,password,mailadressが登録・ログイン・データの確認ができるユーザー管理APIを作成する
ユーザーが登録する → データ保存(例:リスト)
↓
ユーザーがログインする → 正しい情報かチェック
↓
ログイン成功した人だけにアクセスを許可する(JWTで実現)
学んだこと
まずはchatgptにハッシュ化・JWT無しでコードを書いてもらった。
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
app = FastAPI()
# --- ユーザーモデル ---
class User(BaseModel):
username: str
email: str
password: str
# --- 仮のDB(リストで代用) ---
users_db = []
# --- ユーザー登録 ---
@app.post("/register")
def register_user(user: User):
# 同じメールがすでに登録されているかチェック
for u in users_db:
if u.email == user.email:
raise HTTPException(status_code=400, detail="Email already registered")
users_db.append(user)
return {"message": "User registered successfully"}
# --- ユーザー一覧取得 ---
@app.get("/users")
def get_users():
return users_db
# --- ログイン ---
@app.post("/login")
def login(user: User):
for u in users_db:
if u.email == user.email and u.password == user.password:
return {"message": "Login successful!"}
raise HTTPException(status_code=401, detail="Invalid credentials")
POST /register
↓
FastAPIがデータ(JSON)を受け取る
↓
user: User ← Userクラスの形でデータを受け取る
↓
for u in users_db: ← 登録済みユーザーを順番に確認
├─ if u.email == user.email → エラー(重複)
└─ そうでなければ追加!
↓
users_db.append(user)
↓
return {"message": "登録成功!"}
- HPPTExcetionクラスとはなにか
何か問題があった時に適切にエラーコードを返すために使う。それによりサーバーが落ちるのではなく、エラーメッセージを表示できる。
from fastapi import HTTPException
@app.post("/login")
def login(username: str, password: str):
if username != "admin":
raise HTTPException(status_code=404, detail="User not found")
2.クラスを用いた時のdef文の書き方
User(クラス)は「どんな形の箱か」を定義した設計図。前の行でデータ型を定義したクラスという名の箱があるはず。
class User(BaseModel):
username: str
email: str
password: str
userはそのUserクラスのデータ型に従って格納されたデータを入れる箱(この後にappend関数へ渡される)
def register_user(user: User):
def register_user(実際の中身: クラス名):
3.appendとは何かPOSTメゾットとは何が異なるのか
・POSTは外からデータを送信する通信の方法
・appendはデータベースにデータを登録するというpythonの動作
| 名称 | どこで使う? | 意味・役割 |
|---|---|---|
| append() | Pythonの中 | 「リスト(配列)」の最後にデータを追加する関数(メソッド) |
| POST | Webの通信 | 「データをサーバーに送る」ためのリクエスト方式(HTTPメソッド) |
4.for文とif文
下記のコードはusers_dbにあるユーザー情報をuという変数名で頭から一人ずつ取り出すという意味
for文
for u in users_db:
下記のコードはその users_dbから取り出したuが今回登録しようとしているuserとデータが一致していないか確認する。一致していなければデータベースに登録。一致していればHTTPExcetionクラスを利用する。
if u.email == user.email:
raise HTTPException(status_code=400, detail="Email already registered")
users_db.append(user)
4.appendメゾット
append()とはリストにデータを追加するための機能
だから「どのリストに追加するのか」を明示するために下記の様に書く
users_db.append(user)
処理を行う対象.メゾット名(user)
リスト型に対して利用できるその他のメゾット
users_db(リスト)
│
├─ append() → データを後ろに追加
├─ remove() → データを削除
├─ sort() → 並べ替え
└─ clear() → 全削除
私の疑問→appendって関数ではないの?メゾットと関数の違いとは?
関数とは、「何かを渡す(引数を渡す)」と、結果を返してくれる処理。どんな型(文字列・リストなど)でも関係なく使えます。
メソッドとは、「特定の型にくっついている関数」です。
つまり「その型専用の関数」と思ってOK。
5.POSTメゾットには引数があるのにGETメゾットにはない理由
今回のGETメゾットの場合は、ユーザーが「/users」にアクセスした時、サーバーはusers_db の中身を送るだけなのでデータの箱は必要ない。
POSTメゾットは、ユーザーが「新しい情報(例:名前・メール)」をサーバーに送る時サーバーはデータを受け取るための箱が必要となる。
「クライアント → サーバー」方向に何か渡す時は引数が必要になり、
/users/1 のように特定IDだけ取得する場合などは、GETでも引数を使うパターンがあるので要注意!
6.ファイルの名前変更
前回作成したWEEK2フォルダのMain2.pyをMain.pyへ変更したい。
ファイルの移動は「mv」と覚えていたが、リネームをしたい場合も「mv」を使える。
同じフォルダ内でファイル名だけ変える
mv main2.py Main.py
フォルダを移動
mv main2.py week2/
week2フォルダに移動しつつ名前も変える
mv main2.py week2/user_api.py
躓いたところ
特になし
所感
ユーザー登録・ログイン・確認までの流れをすべて確認できるコードを学んだ。
1年前に研修で学習したJAVAと違ってややこしいと感じる場面は少なく、コードというより英語の文を書いているような気分でコードを書くことができた。
独学で初学者が勉強するにはうってつけの言語だと感じた。
今回ユーザー登録からログイン~登録の確認まで学んだので、今後はパスワードのハッシュ化を実装したいと思う。