コンテンツにスキップ

12 パスワードのハッシュ化

通常、パスワードは平文のままでは保存しません。 ハッシュ化(不可逆の暗号化)を行って保存します。

これには以下の理由があります。

  • データベースが流出したときにもパスワードが流出しないようにするため
  • 管理者にもパスワードが分からないようにするため

12.1 upass.py

既存のパスワードをハッシュ化するため、upass.py を作成し以下を貼り付け、実行します。 generate_password_hashはパスワードのハッシュを生成する関数です。

from flask import Flask
from werkzeug.security import generate_password_hash
from models import db, User

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///photo.db'

db.init_app(app)

with app.app_context():
    # tanaka の upass を "aaa" のハッシュに更新
    tanaka = User.query.filter_by(uname='tanaka').first()
    if tanaka:
        tanaka.upass = generate_password_hash("aaa")
        print("tanaka のパスワードを更新しました。")

    # yamada の upass を "bbb" のハッシュに更新
    yamada = User.query.filter_by(uname='yamada').first()
    if yamada:
        yamada.upass = generate_password_hash("bbb")
        print("yamada のパスワードを更新しました。")

    db.session.commit()

12.2 app.py

app.pyで以下のインポートを付け加えます。

from werkzeug.security import check_password_hash, generate_password_hash

check_password_hashは平文のパスワードをハッシュ化し、データベースのハッシュと比較します。

login関数で認証している部分を以下に置き換えます。 check_password_hash では入力パスワード(平文)とデータベースのパスワード(ハッシュ)を比較します。

    # ユーザ名で検索
    row = User.query.filter(User.uname == uname).first()

    # ユーザがいない、またはパスワードが異なる
    if row is None or not check_password_hash(row.upass, upass):
        flash("ユーザ名またはパスワードが違います")
        return redirect("/login")
    else:
        session['uid'] = row.uid
        return redirect("/")

ログインできるかを検証します。