2015-04-23 77 views
0

我有一個用戶模型,具有使用Werkzeug的set_password_hashcheck_password_hash函數設置和檢查密碼的功能。爲什麼check_password_hash在這個登錄視圖中總是返回False?

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') 

check_password閃蒸結果始終是 「假」。我究竟做錯了什麼?

+0

我這樣傳遞:'new_user = User(username,password)'然後''set_password''函數對它進行加密。 – user3448282

+0

'from werkzeug import generate_password_hash,check_password_hash' – user3448282

回答

2

您已將User.password定義爲長度爲15,但密碼散列長度超過15個字符。所以當你稍後進行比較時,它不會是相同的值,它會被截斷。

解決的辦法是定義一個更長的長度來容納散列的長度,或者使用一個不關心長度的數據庫(PostgreSQL,SQLite),並且根本不要設置列的長度(這是最好的)。

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

還有第二個問題:你調用check_password與存儲的哈希值,不與用戶輸入。

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

以下是演示密碼正常工作的一個小例子。

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 
+0

因此,我應該只更改'User.password'的長度,對吧?我問你,因爲我做到了,我仍然**錯了**。 – user3448282

+0

@ user3448282你是否改變了數據庫中的列?否則,它仍然會有舊的定義。你使用的是哪個數據庫? – davidism

+0

我正在使用SQLite,當然,我在更改之後生成了它。 – user3448282

相關問題