falsk框架之Werkzeug实现散列密码

在做一个系统时,用户登录模块必不可少,当然用户名和密码就少不了了。在我接触flask框架之前,我都一直将密码直接保存进数据库的,大概就是这样👇哈哈哈哈哈啊哈哈哈哈很小新
在这里插入图片描述
最近在学习flask框架,今天看到可以通过Werkzeug外部库来实现密码的加密功能。将密码加密后再保存到数据库中,大概就是这样的👇
在这里插入图片描述


一、函数介绍

通过使用Werkzeug库中的security模块,可以很方便的实现密码散列值的计算功能。只需要如下两个函数即可实现这一功能,分别在注册用户和验证用户阶段。

  • generate_password_hash(password:str):功能是将原始密码作为输入,以字符串形式输出密码的散列值,输出的值可保存在用户数据库中。函数的参数其实还有method: str = "pbkdf2:sha256",salt_length: int = 16,这个是默认参数不用多管。咱们实现就传入password一个参数就够了。

  • check_password_hash(pwhash: str, password: str):功能是检查给出的hash密码与明文密码是否相符,参数pwhash是从数据库中取回的密码散列值,password是用户输入的密码。如果返回值为True,则表明密码正确;如果为False,则表明密码不正确。


二、功能实现

1.导包

这里导入的包只写了实现加密密码用到的包,如果您的项目中所需其他的包请读者自行添加。

from werkzeug.security import check_password_hash,generate_password_hash
2.User模型

定义实体类模型时,请记得要实现generate_password_hash()check_password_hash()两个函数,实现很简单。

class User(db.Model):
    __tablename__ = 'b_user'
    id = db.Column(db.Integer, primary_key=True,autoincrement=True)
    username = db.Column(db.String(30),unique=True)
    password = db.Column(db.String(256))
    
    def __init__(self, username, password):
        self.username = username
        self.password = password

    def set_password(self,password):
        self.password = generate_password_hash(password)

    def check_password(self,password):
        return check_password_hash(password)
3.用户注册

我写模型的时候,实例化对象需要传入username和password两个参数,实例化完成后,再用实例对象调用set_password()方法将对象的明文密码修改为hash密码,然后再将实例对象插入数据库。

@app.route('/regist',methods=['GET','POST'])
def regist():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        if username is None or password is None:
            error = 'username or password is empty!'
            return render_template('login.html',error=error)
        else:
            try:
                user = User(username,password)
                user.set_password(password)
                db.session.add(user)
                db.session.commit()
                flash('Your regist successfully')
                return redirect(url_for('login'))
            except:
                flash('error')
                return redirect(url_for('login'))
    else:
        return render_template('regist.html')
5.用户登录

在这里踩了个小坑,就是最开始执行User.query.filter_by(username=username).first()时,最开始我没有使用first()函数,发现返回的值的类型并不是User实例对象,而是flask_sqlalchemy.BaseQuery,值就是sql语句。所以在这去学习了filter()filter_by()函数以及first()all()函数。我在这篇blog看明白的,博主讲的很好。附上链接。

bloghttps://blog.csdn.net/weixin_45222544/article/details/103210684

代码里面的password1是表单输入的明文密码,然后通过用户名查询实体类用户,通过user.password获得注册时保存进数据库的hash密码。

@app.route('/login',methods=['GET','POST'])
def login():
    error = None
    print(get_flashed_messages())
    if request.method == 'POST':
        username = request.form.get('username')
        password1 = request.form.get('password')
        user = User.query.filter_by(username=username).first()
        password_is_true = check_password_hash(user.password,password1)
        if password_is_true == False:
            return '您输入的用户名和或密码不正确'
        else:
            session['logged_in'] = True
            flash('You were logged in')
            return redirect(url_for('show_entries'))
    else:
        return render_template('login.html',error=error)
6.启动程序
if __name__ == '__main__':
    app.run(debug=True)

请读者注意,本文所示代码并不全,无法直接运行,只是讲解密码加密的大致流程。如果您需要整个项目,我放在百度云了,请自行下载。另外大家如果有什么其他的见解或者我写博客有不足的地方,欢迎大家提出来!如果您觉得我写的还不错,点个赞支持一下,后面我会写更多东西出来与大家分享,谢谢

链接:https://pan.baidu.com/s/1bjI8GPbtOnDoO1-HLdiFlg
提取码:ny9j


2022.3.14更新
另外项目运行时,请先进行数据库迁移:

  1. python dbinit.py db init
  2. python dbinit.py db migrate
  3. python dbinit.py db upgrade
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值