# 简介
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
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)