備忘録です。
今回は、ユーザー設定にパスワードを付加し、DBにハッシュ化して保存する設定の備忘録です。
hash
werkzeugでハッシュ化
その1 werkzeugライブラリのインストール
# app.py
from werkzeug.security import generate_password_hash, check_password_hash
その2 Usersテーブルの編集
テーブルを編集するので一旦、これまで登録していたユーザーは削除します。特にパスワードなどを扱う場合は必ず消しておいた方が良いです。
#app.py
class Users (db.Model):
id = db.Column(db.Integer, primary_key=True )
name = db.Column(db.String(255 ), nullable=False )
email = db.Column(db.String(120 ), nullable=False , unique=True )
u_created_at = db.Column(db.DateTime, default=datetime.now(pytz.timezone('Asia/Tokyo' )))
password_hash = db.Column(db.String(128 ))
@ property
def password (self):
raise AttributeError ('password is not a readable!' )
@ password.setter
def password (self, password):
self.password_hash = generate_password_hash(password)
def verify_password (self, password):
return check_password_hash(self.password_hash, password)
def __repr__ (self):
return '<Name %r>' % self.name
上記の「ここから追加」〜「ここまで追加」部分を追加します。
その3 flask shellでチェック
flask shellはコマンドライン インターフェイス で多くのことを自動的にやってくれるものとのことです。 Shellを使った作業 — Flask Documentation (2.0.x)
コマンドライン で上記の設定をチェックしてみるとこうなります。
$ flask shell
>>> from app import Users# uというユーザーを作成
>>> u = Users()
>>> u.password = 'reo'
>>> u.password
Traceback (most recent call last):
File "<console>" , line 1 , in <module>
File "/Users/yourfolda/app.py" , line 114 , in password
raise AttributeError ('password is not a readable!' )
AttributeError : password is not a readable!
u.passwordのところでハッシュを作っていないのでエラーを吐き出しています。
>>> u.password_hash
'pbkdf2:sha256:260000$TdDFXjnQWPjEHvKo$514ee6d136c6c29857b7d00ab679a09313ac34dc9503858926e295b97c820344'
>>> u.verify_password('reo' )
True
>>>
setterが起動してpasswordのハッシュができたようです。
最後にverify_password関数で確認するとこのハッシュのパスワードが'reo'であることが確認できます。
その4 DBにプッシュ
モデルの修正をしたのでDBにプッシュします。
$ flask db migrate -m 'コメント'
$ flask db upgrade
その5 ユーザー追加用フォームにパスワードの入力欄を追加
# add_user.html
<form method="POST" >
{{ form.hidden_tag() }}
{{ form.name.label(class ="form-label" ) }}
{{ form.name(class ="form-control" ) }}
<br/>
{{ form.email.label(class ="form-label" ) }}
{{ form.email(class ="form-control" ) }}
<br/>
{{ form.password_hash.label(class ="form-label" ) }}
{{ form.password_hash(class ="form-control" ) }}
<br/>
{{ form.password_hash2.label(class ="form-label" ) }}
{{ form.password_hash2(class ="form-control" ) }}
<br/>
{{ form.submit(class ="btn btn-secondary" ) }}
</form>
その6 フォームの編集
class UserForm (FlaskForm):
name = StringField('Name' , validators=[DataRequired()])
email = StringField('Email' , validators=[DataRequired()])
password_hash = PasswordField('Password' , validators=[DataRequired(), EqualTo('password_hash2' , message='Password Must Match!' )])
password_hash2 = PasswordField('Confirm Password' , validators=[DataRequired()])
submit = SubmitField('Submit' )
PasswordFieldでセットすると、入力時に[・・・・・]という感じで表向き表示されないようなフィールドとなります。
その7 ユーザーを登録する関数を編集
# app.py
@ app.route ('/user/add' , methods=['GET' , 'POST' ])
def add_user ():
name = None
form = UserForm()
if form.validate_on_submit():
user = Users.query.filter_by(email=form.email.data).first()
if user is None : # passwordをhash化する hashed_pw = generate_password_hash(form.password_hash.data, "sha256") user = Users(name=form.name.data, email=form.email.data, password_hash=hashed_pw) db.session.add(user)
db.session.commit()
name = form.name.data
form.name.data = ''
form.email.data = ''
form.password_hash.data = ''
our_users = Users.query.order_by(Users.u_created_at)
return render_template('add_user.html' , form=form, name=name, our_users=our_users)
generate_password_hash関数を呼び出してパスワードをハッシュ化する必要があります。そしてハッシュ化したパスワードをDBに登録します。