为什么在这个登录视图中check_password_hash总是返回False? [英] Why is check_password_hash always returning False in this login view?

查看:296
本文介绍了为什么在这个登录视图中check_password_hash总是返回False?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用户模型,使用Werkzeug的 set_password_hash check_password_hash 函数设置和检查密码。 / p>

models.py

  class User(db.Model):
id = db.Column(db.Integer,primary_key = True)
username = db.Column(db.String(15),unique = True)
password = db.Column(db。 String(15))
tasks = db.relationship('Task',backref ='author',lazy ='dynamic')

def __init __(self,username,password):
self.username =用户名
self.set_password(密码)
$ b $ def set_password(self,password):
self.password = generate_password_hash(password)

def check_password(self,password):
return check_password_hash(self.password,password)

login.py

  def post(self):
username = flask.request.form [用户名']
passwd = flask.request.form ['passwd']
user = User.query.filter_by(username = username).first()
flask.flash(user.check_password(user.password))
如果user和user.check_password(user.password):
flask.session ['username'] = username
else:
flask.flash(User does not exist or密码是inccorect)
返回flask.render_template('login.html')
返回flask.render_template('index.html')



check_password 的闪现结果总是为False。我在做什么错了?

解决方案

您已经定义了 User.password 长度为15,但密码哈希长度超过15个字符。所以当你稍后进行比较时,它不会是相同的值,它将被截断。



解决方案是定义更长的长度以适应长度或者使用一个不关心长度的数据库(PostgreSQL,SQLite),并且根本不需要设置列的长度(这是可取的)。

  password = db.Column(db.String)#no length 
#or
password = db.Column(db.String(255))#some还有另外一个问题:你们有一些问题,比如:使用存储的散列重新调用 check_password ,而不是使用用户输入。

 #wrong 
user.check_password(user.password)
#应该是
user.check_password(passwd)






以下是一个小例子,演示密码正常工作。 $ p> 从sqlalchemy.ext.declarati导入sqlalchemy作为sa
从sqlalchemy.orm导入declarative_base
从werkzeug.security导入Session
import generate_password_hash,check_password_hash
$ b $ engine = sa.create_engine('sqlite://',echo = True)
session = Session(引擎)
Base = declarative_base(引擎)

class用户(Base):
__tablename__ ='user'
$ b $
username = sa.Column(sa.String,nullable = False,unique = True)
password = sa.Column('password' ,sa.String)
$ b $ def set_password(self,secret):
self.password = generate_password_hash(secret)
$ b $ def check_password(self,secret):
返回check_password_hash(self.password,secret)

Base.metadata.create_all()

u = User(username ='davidism')
u。 set_password('cabbage')
session.add(u)
session.commit()

u = session.query(User).filter_by(username ='davidism')。一()
打印(上密码)
#pbkdf2:sha1:1000 $ w9jx4Egp $ b420d784ac6ad0575e4a9a908bb4679826e56f5f
print(u.check_password('cabbage'))
#True
pre>

I have a user model with functions to set and check a password using Werkzeug's set_password_hash and check_password_hash functions.

models.py

class User(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    username = db.Column(db.String(15), unique = True)
    password = db.Column(db.String(15))
    tasks = db.relationship('Task', backref='author', lazy='dynamic')

    def __init__(self, username, password):
        self.username = username
        self.set_password(password)

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

    def check_password(self, password):
        return check_password_hash(self.password, password)

login.py

def post(self): 
    username = flask.request.form['username']
    passwd = flask.request.form['passwd']
    user = User.query.filter_by(username = username).first()
    flask.flash(user.check_password(user.password))
    if user and user.check_password(user.password):
        flask.session['username'] = username
    else:
        flask.flash("User doesn't exist or password is inccorect.")
        return flask.render_template('login.html')
    return flask.render_template('index.html')

The flashed result of check_password is always "False". What am I doing wrong?

解决方案

You've defined User.password to have a length of 15, but the password hash is longer than 15 characters. So when you go to compare it later, it will not be the same value, it will be truncated.

The solution is to either define a longer length to accommodate the length of the hash, or use a database that doesn't care about length (PostgreSQL, SQLite) and don't set a length for the column at all (this is preferable).

password = db.Column(db.String)  # no length
# or
password = db.Column(db.String(255))  # some longer length


There's also a second problem: you're calling check_password with the stored hash, not with the user input.

# wrong
user.check_password(user.password)
# should be
user.check_password(passwd)


The following is a small example that demonstrates the password working correctly.

import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import Session
from werkzeug.security import generate_password_hash, check_password_hash

engine = sa.create_engine('sqlite://', echo=True)
session = Session(engine)
Base = declarative_base(engine)

class User(Base):
    __tablename__ = 'user'

    id = sa.Column(sa.Integer, primary_key=True)
    username = sa.Column(sa.String, nullable=False, unique=True)
    password = sa.Column('password', sa.String)

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

    def check_password(self, secret):
        return check_password_hash(self.password, secret)

Base.metadata.create_all()

u = User(username='davidism')
u.set_password('cabbage')
session.add(u)
session.commit()

u = session.query(User).filter_by(username='davidism').one()
print(u.password)
# pbkdf2:sha1:1000$w9jx4Egp$b420d784ac6ad0575e4a9a908bb4679826e56f5f
print(u.check_password('cabbage'))
# True

这篇关于为什么在这个登录视图中check_password_hash总是返回False?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆