tl;dr -- SQLAlchemy を使用して MySQL DB にパスワードを挿入する前に、PassLib などの Python 側のライブラリを使用してパスワードをハッシュするにはどうすればよいですか?
さて、私はこれを理解しようとして1日か2日机に頭をぶつけていたので、ここに行きます:
Pyramid/SQLAlchemy を使用して Web アプリケーションを作成しており、MySQL データベースの Users テーブルとやり取りしようとしています。
最終的には、次のようなことをしたいと考えています。
パスワードをハッシュと比較します。
if user1.password == 'supersecret'
新しいパスワードを挿入します。
user2.password = 'supersecret'
パスワードがデータベースに送られる前に PassLib を使用してパスワードをハッシュできるようにしたいのですが、ソルト化されていないため、組み込みの MySQL SHA2 関数を使用するのは好きではありません。
ただし、試してみると、SQL側の関数を使用してこれが機能しています。
from sqlalchemy import func, TypeDecorator, type_coerce
from sqlalchemy.dialects.mysql import CHAR, VARCHAR, INTEGER
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column
class SHA2Password(TypeDecorator):
"""Applies the SHA2 function to incoming passwords."""
impl = CHAR(64)
def bind_expression(self, bindvalue):
return func.sha2(bindvalue, 256)
class comparator_factory(CHAR.comparator_factory):
def __eq__(self, other):
local_pw = type_coerce(self.expr, CHAR)
return local_pw == func.sha2(other, 256)
class User(Base):
__tablename__ = 'Users'
_id = Column('userID', INTEGER(unsigned=True), primary_key=True)
username = Column(VARCHAR(length=64))
password = Column(SHA2Password(length=64))
def __init__(self, username, password):
self.username = username
self.password = password
これは、http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DatabaseCryptの例 2 からコピーしたものです。
これで動作し、組み込みの MySQL SHA2 関数を ( を呼び出すことでfunc.sha2()
) 使用して、自分のやりたいことを正確に行うことができます。ただし、現在、これを Python 側の PassLib に置き換えようとしています。
PassLib は 2 つの関数を提供します。1 つは新しいパスワード ハッシュを作成するためのもので、もう 1 つはパスワードを検証するためのものです。
from passlib.hash import sha256_crypt
new_password = sha256_crypt.encrypt("supersecret")
sha256_crypt.verify("supersecret", new_password)
これを実際に実装する方法がよくわかりません。すべてのドキュメントを読んだ結果、TypeDecorator の別の形式、カスタム型宣言、ハイブリッド値、またはハイブリッド プロパティのいずれかであると思います。私はこれに従ってみましたが、それは本当に意味がなく、そこに提案されているコードは実際に実行されません。
では、私の質問を要約すると、=
and==
演算子をオーバーロードして、適切なハッシュ関数を介して実行するにはどうすればよいでしょうか?