发送curl请求时,使用bcrypt driver.db进行Eve身份验证错误

时间:2017-03-01 19:48:36

标签: python rest curl flask eve

我使用bcrypt来验证我的资源,并使用用户名和密码将帐户存储在mydatabase中。我已将密码作为哈希值手动存储在数据库中,如下所示:

我启动了python bash并输入以下代码:

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

然后我复制了print的输出并通过POST请求(没有身份验证)将其存储在帐户表中:

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

我使用SQLAlchemy,而且eve也是最新的(版本:0.7.1)。 好吧,我使用Bcrypted Authentication请求例如人员资源,如下所示:

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'

由于某种原因,db属性不可用。我也尝试使用Eve.app.data.driver.db,我尝试从flask中导入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:password@localhost: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

希望有人可以帮助我。

1 个答案:

答案 0 :(得分: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。