tornado 用户密码 bcrypt加密

2023-03-06 19:44:44 浏览数 (1)

# 简介

bcrypt 可以通过加盐的方式对密码进行加密,更加的安全可靠。

该项目的github地址: tornado_learning.git (opens new window)

优点

md5加密,每个对应的明文密码,对应的是一样的加密的密文,比较容易的进行解密。而bcrypt每一次的明文密码得到的是不同的加密的密文,因为密文是通过随机的盐结合加密,所以更加安全。

# python 如何使用bcrypt 栗子

代码语言:javascript复制
from bcrypt import hashpw, gensalt

# 这个是随机生成的盐
salt = gensalt(12)

# 这个是通过盐去加密
passwd = hashpw("123456".encode('utf8'), salt)

# 将输入的明文密码与密文密码进行加密,是否等于密文密码。
hashpw(input_passwd.encode('utf8'), passwd) == passwd

# tornado 使用 bcrypt 加密密码栗子。

# 创建user model

在user model中的密码字段使用自定义的PasswordField.

代码/apps/user/models.py

代码语言:javascript复制
class PasswordHash(bytes):
    def check_password(self, password):
        """
        比较传入的密码和数据库中的密码是否匹配
        :param password:
        :return:
        """
        password = password.encode('utf-8')
        return hashpw(password, self) == self

class PasswordField(BlobField):
    def __init__(self, iterations=12, *args, **kwargs):
        if None in (hashpw, gensalt):
            raise ValueError('Missing library required for PasswordField: bcrypt')
        self.bcrypt_iterations = iterations
        self.raw_password = None
        super(PasswordField, self).__init__(*args, **kwargs)

    def db_value(self, value):
        """
        将python的值转换成存入数据库的值
        存入数据库的值,是通过bcrypt加密后的密文。
        :param value:
        :return:
        """
        if isinstance(value, PasswordHash):
            return bytes(value)

        if isinstance(value, str):
            value = value.encode('utf-8')
        salt = gensalt(self.bcrypt_iterations)
        return value if value is None else hashpw(value, salt)

    def python_value(self, value):
        """
        将数据库中的值转换成python中的值
        这个值是一个PasswordHash对象。该对象提供比较密码的方法。
        :param value:
        :return:
        """
        if isinstance(value, str):
            value = value.encode('utf-8')

        return PasswordHash(value)

class User(BaseModel):
    username = CharField(max_length=16, verbose_name="用户名", index=True, unique=True)
    password = PasswordField(verbose_name="密码")
    address = CharField(max_length=200, null=True, verbose_name="地址")

# 注册的handler

注册的接口

代码: /apps/user/handler.py

代码语言:javascript复制
class RegisterHandler(BaseHandler):

    async def post(self):

        ret_data = {}

        registerForm = RegisterForm(self.request.arguments)
        if registerForm.validate():
            username = registerForm.username.data

            try:
                exist_user = await self.application.objects.get(User, username=username)
                ret_data["username"] = "用户名已经存在"
            except User.DoesNotExist as e:
                user = await self.application.objects.create(User, **registerForm.data)
                ret_data["id"] = user.id
        else:
            self.set_status(400)
            for field in registerForm.erros:
                ret_data[field] = registerForm[field][0]

        return self.finish(ret_data)

0 人点赞