【FastAPI】パスワードのハッシュ化【SQLAlchemy】

データベースへパスワードのなどの機密情報を保存する場合にはハッシュ化する必要があります

djangoなどはその辺よしなにやってくれるのですが、今回はFastAPIでのパスワードハッシュの方法を記載いたします。

sqlalchemyによるデータベースとモデルの作成は下記をご参照ください。

この記事のサンプルコード

目次

必要なライブラリのインストール

まずは下記ライブラリをインストールします。

  • sqlalchemy データベース操作
  • passlib bcrypt パスワードの暗号化

に必要です。

pip install sqlalchemy passlib bcrypt

モデルの作成

Userモデルを作成します。

from db.database import Base
from sqlalchemy import Column
from sqlalchemy.sql.sqltypes import Boolean, Integer, String

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True, index=True)
    username = Column(String)
    email = Column(String)
    password = Column(String)
    is_active = Column(Boolean, default=True)

パスワードのハッシュ化関数の作成

ドキュメントを参考にしながら、ハッシュ化を行う関数を作成します。

db/hash.pyを作成しました。

from passlib.context import CryptContext

pwd_cxt = CryptContext(schemes=['bcrypt'], deprecated='auto')

class Hash():
    def get_password_hash(password: str):
        return pwd_cxt.hash(password)

    def verify_password(hashed_password, plain_password):
        return pwd_cxt.verify(plain_password, hashed_password)
  • get_password_hash パスワードハッシュ化
  • verify_password パスワード認証用

を作成しました。

UserのBaseModelを作成

  • 新規作成用
  • 返り値用

BaseModelを作成します。schema.pyを作成しました。

from pydantic import BaseModel

class UserBase(BaseModel):
    username: str
    email: str

class UserCreate(UserBase):
    password: str

class UserDisplay(UserBase):
    id: int
    class Config():
        orm_mode = True

ユーザー追加の関数を作成

データベースへ登録用のユーザー追加関数を作成します。

パスワードの追加時に、先ほど作成したハッシュ化関数を使用しています。

from db.hash import Hash
from sqlalchemy.orm.session import Session
from schemas import UserCreate
from db.models import User


def create_user(db: Session, request: UserCreate):
    new_user = User(
        username = request.username,
        email = request.email,
        password = Hash.get_password_hash(request.password)
    )
    db.add(new_user)
    db.commit()
    db.refresh(new_user)
    return new_user

エンドポイントの作成

ユーザー作成用のエンドポイントを作成します。

from schemas import UserCreate, UserDisplay
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from db.database import get_db
from db import db_user


router = APIRouter(
  prefix='/user',
  tags=['user']
)

@router.post('/', response_model=UserDisplay)
def create_user(request: UserCreate, db: Session = Depends(get_db)):
  return db_user.create_user(db, request)

main.pyにはrouterを登録をしておきます。

app.include_router(users.router)

動作確認

登録ができ、レスポンスも返ってきています。パスワードがハッシュ化されているか、直接データベースを覗いてみましょう。

ハッシュ化されたパスワードの確認

使用したデータベースsqliteから直接覗いてみましょう。

sqlite3 fastapi.db

sqliteの中に入り、SQL文でデータを参照してみます。

sqlite> select username, password from users;

string|$2b$12$ihIpYEie47DVD9gBfGB3rON8ly5FyTHJemYsVvK5izA3EKgOxRo36
string|$2b$12$N7oTH8fzaL8SeVqbuRyKz.ChRa4v9ueen28dpUMvpSuOiNXPvUMn.
selfmethods|$2b$12$Y8du1e0pvdyLTzexXELPjO23TlcYhf2ZY73HLLAubX8o4bsmjBWmy

パスワードがハッシュ化された状態で保存されていることが分かりました!

ユーザー認証などの処理などは下記をご参照ください。

この記事のサンプルコード

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!

コメント

コメントする

目次
閉じる