tl; dr-在使用SQLAlchemy将密码插入MySQL数据库之前,如何使用PassLib之类的Python端库对密码进行哈希处理?

好吧,所以我一两天一直在想办法解决这个问题,下面是这样:

我正在使用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

这是从示例2的http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DatabaseCrypt复制而来的

这样可以正常工作,并允许我使用内置的MySQL SHA2函数(通过调用func.sha2())并完全执行我想要的操作。但是,现在我正在尝试在Python端将其替换为PassLib。

PassLib提供两种功能:一种用于创建新的密码哈希,另一种用于验证密码:

from passlib.hash import sha256_crypt

new_password = sha256_crypt.encrypt("supersecret")

sha256_crypt.verify("supersecret", new_password)

我还不太清楚如何真正实现这一点。阅读所有文档后,我认为它是TypeDecorator的不同形式,自定义类型声明,混合值或混合属性。我尝试遵循this,但这对我来说真的没有意义,那里的建议代码也没有真正运行。

因此,总而言之,我如何重载===运算符,以便它们通过适当的哈希函数运行事物?

最佳答案

PasswordType中的sqlalchemy-utils应该最适合此问题。它使用passlib。从文档中摘录:


class Model(Base):
    password = sa.Column(PasswordType(
        schemes=[
            'pbkdf2_sha512',
            'md5_crypt'
        ],
        deprecated=['md5_crypt']
    ))


target = Model()
target.password = 'b'
# '$5$rounds=80000$H.............'
target.password == 'b'
# True

关于python - SQLAlchemy和PassLib,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14968300/

10-12 19:40