Eve Authentication с ошибкой bcrypt driver.db при отправке запроса curl

Я использую bcrypt для аутентификации своих ресурсов, и в моей базе данных хранятся учетные записи с именем пользователя и паролями. Я сохранил пароли вручную в виде хэшей в базе данных следующим образом:

Я запустил python bash и набрал следующий код:

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

Затем я скопировал вывод печати и сохранил его в таблице учетных записей с помощью запроса 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, и я попытался импортировать 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)

table.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

Надеюсь, кто-нибудь сможет мне помочь.


person mbijou    schedule 01.03.2017    source источник


Ответы (1)


Что-то в этом роде должно работать:

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.

person dkellner    schedule 16.04.2017