tornado 用户密码 bcrypt加密

20 篇文章 0 订阅
6 篇文章 0 订阅

简介

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

该项目的github地址: tornado_learning.git

优点

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

python 如何使用bcrypt 栗子

 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

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

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
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值