2017-03-01 74 views
1

我使用bcrypt对我的资源进行身份验证,并使用用户名和密码将帐户存储在mydatabase中。我已经手动保存密码在数据库中的哈希值如下:Eve发送curl请求时使用bcrypt driver.db错误进行身份验证

我开始蟒蛇bash和在下面的代码类型:

import bcrypt 
password = u'passwordtobehashed' 
password_hashed = bcrypt.hashpw(password, bcrypt.gensalt()) 
print (password_hashed) 

然后我复制打印的输出和存储它的账表通过POST请求(W/O认证):

curl -d '{"username": "someuser", "password": "somehashedpassword", "roles_id": 1}' -H 'Content-Type: application/json' http://127.0.0.1:5000/account 

嗯,我使用SQLAlchemy和夏娃也是最新版(版本:0.7.1)。 那么我请求例如人们使用Bcrypted验证如下资源:

curl -u username 127.0.0.1:5000/people 

然后输入我的密码,我收到以下错误:

File "/home/vagrant/erpghost/restapi/oldtrivial.py", line 57, in check_auth 
    accounts = app.data.driver.db['account'] 
AttributeError: 'SQLAlchemy' object has no attribute 'db' 

出于某种原因,该数据库属性不可用。我也尝试使用Eve.app.data.driver.db,我尝试从烧瓶导入current_app,但都没有奏效。

那么这里是我的代码:

oldtrivial.py


from eve.auth import BasicAuth 
from eve import Eve 
from eve_sqlalchemy import SQL 
from eve_sqlalchemy.validation import ValidatorSQL 
import bcrypt 
from connection import connect 
from connection import Base 

con, meta = connect() 
Base.metadata.create_all(con) 


class BCryptAuth(BasicAuth): 
    def check_auth(self, username, password, allowed_roles, resource, method): 
     accounts = app.data.driver.db['account'] 
     account = accounts.find_one({'username': username}) 
     return account and \ 
      bcrypt.hashpw(password, account['password']) == account['password'] 

app = Eve(validator=ValidatorSQL, data=SQL, auth=BCryptAuth) 

db = app.data.driver 
Base.metadata.bind = db.engine 
db.Model = Base 
db.create_all() 


if __name__ == '__main__': 
    app.run(debug=True, use_reloader=False) 

tables.py


from sqlalchemy.orm import column_property 
from sqlalchemy import Column, Integer, String, DateTime, func, ForeignKey 
from connection import connect 
from eve.auth import BasicAuth 
from connection import Base 
from sqlalchemy.orm import relationship 

con, meta = connect() 

class CommonColumns(Base): 
    __abstract__ = True 
    _created = Column(DateTime, default=func.now()) 
    _updated = Column(DateTime, default=func.now(), onupdate=func.now()) 
    _etag = Column(String(40)) 


class People(CommonColumns): 
    __tablename__ = 'people' 
    _id = Column(Integer, primary_key=True, autoincrement=True) 
    firstname = Column(String(80)) 
    lastname = Column(String(120)) 
    fullname = column_property(firstname + " " + lastname) 


class Roles(CommonColumns): 
    __tablename__ = 'roles' 
    _id = Column(Integer, primary_key=True, autoincrement=True) 
    role = Column(String(80)) 


class Account(CommonColumns): 
    __tablename__ = 'account' 
    _id = Column(Integer, primary_key=True, autoincrement=True) 
    username = Column(String(50), nullable=False, unique=True) 
    password = Column(String(200), nullable=False) 
    roles = relationship("Roles", backref="account") 
    roles_id = Column(Integer, ForeignKey('roles._id')) 

settings.py


from eve_sqlalchemy.decorators import registerSchema 
from eve.utils import config 
from tables import People 
from tables import Account 
from tables import Roles 


registerSchema('people')(People) 
registerSchema('roles')(Roles) 
registerSchema('account')(Account) 

DOMAIN = { 
     'people': People._eve_schema['people'], 
     'roles': Roles._eve_schema['roles'], 
     'account': Account._eve_schema['account'], 
} 

DOMAIN['account'].update({ 
    'additional_lookup': { 
     'url': 'regex("[\w]+")', 
     'field': 'username' 
    }, 
    'cache_control': '', 
    'cache_expires': 0, 
    'allowed_roles': ['superuser', 'admin'], 
    'authentication': None, 
}) 

SQLALCHEMY_DATABASE_URI = 'postgresql://databaseuser:[email protected]:5432/database' 

RESOURCE_METHODS = ['GET', 'POST'] 

ITEM_METHODS = ['GET', 'DELETE', 'PATCH', 'PUT'] 

DEBUG = True 

config.ID_FIELD = config.ITEM_LOOKUP_FIELD = '_id' 

DOMAIN['people']['id_field'] = config.ID_FIELD 
DOMAIN['roles']['id_field'] = config.ID_FIELD 
DOMAIN['account']['id_field'] = config.ID_FIELD 

希望有人能帮助我。

回答

2

沿着这些线路的东西应该工作:

from flask import current_app 
from tables import Account 

# ... 

def check_auth(...): 
    session = current_app.data.driver.session 
    return session.query(Account) \ 
        .filter(Account.username == username, 
          Account.password == hashed_password) \ 
        .count() > 0 

我想你已经尽力模仿代码http://python-eve.org/authentication.html#basic-authentication-with-bcrypt?这是为了使用Mongo-DB而不是SQLAlchemy。

相关问题