2

我想根据 Python eve restframework 中用户的访问权限实现一个“更复杂”的过滤器。

问题

我们有令牌认证,用户帐户是在TokenAuth类中获取的。用户有一些合同,每个合同都有账单。我想实现一个端点 /bills 来显示他的合同账单。我们使用mongodb.

为了更好地理解,类似于 SQL 语句"SELECT * FROM bills WHERE bills.contract IN user.contracts"

user { contracts : ["a","b","c"] }
bills { contract: "a" }

背景资料

class TokenAuth(TokenAuthBase):
    def check_auth(self, token, allowed_roles, resource, method):
       users = app.data.driver.db['users']
       TokenAuth.account = users.find_one(lookup)
       ...

(更新)

用户受限资源访问¶ (URRA)

对于用户 1 : n 账单关系的情况,URRA 将完成这项工作。请参阅python eve docs 中的 URRA

在更复杂的情况下,有必要编写自定义过滤器查询。我需要这个选项:)。

更新

我找到了解决方案,请参阅更新的答案。

4

5 回答 5

2

那么预定义的数据库过滤器呢?

bills = {
    'datasource': {
        'source': 'bills',
        'filter': {'field1': 'value1', 'field2': 'value2'}
    }
}

source是一个mongodb集合;filter是一个mongodb查询。它将透明地应用于命中端点的任何请求(在客户端查询之前)。

于 2014-03-10T17:00:58.140 回答
2

感谢 Nicola Iaorcci,我找到了解决方案。

首先,我为每个端点使用自定义身份验证类。

class MyCreditNoteAuth(TokenAuthBase):
   def check_auth(self, token, allowed_roles, resource, method):
        account = app.data.driver.db['users'].find_one({'api_access_token': token})

此方法从 mongodb 获取用户帐户,现在我可以访问他的合同 ID。

其次,仍然在上面的方法中,我在每个请求上更新数据源的过滤器:

mynotes['datasource']['filter']['contract'] = { '$in': account['contracts'] }

现在客户在给定端点上只能看到他自己的“笔记”。

于 2014-03-18T11:28:45.100 回答
1

I think it might be better to do this on a per request basis. Modifying the 'DOMAIN' might lead to cases where multiple people are logged in and sending requests at the same time and the domain changes in between requests depending on how you implement that sort of thing. Mayby something like this would work:

from eve import Eve
from eve.auth import BasicAuth

def pre_get_api_stuff(resource, request, lookup):
    username = request.authorization['username']
    accounts = app.data.driver.db['accounts']
    account = accounts.find_one({'username': username})
    if resource == 'notes':
        lookup.update({'username': username})

app = Eve(auth=BasicAuth)
app.on_pre_GET += pre_get_api_stuff
于 2016-01-15T01:47:40.223 回答
0

您是否查看过用户限制资源访问

快速浏览一下,我会说,通过将用户令牌(或 id,或在您的设置中标识用户的任何内容)与您的账单文档一起存储,然后在bills端点启用 URRA,就可以解决问题。

于 2014-03-09T08:50:12.727 回答
0

更完整的例子如下,假设我们在settings.py中有以下内容

note_schema = {
    'user_id': {
        'type': 'objectid',
        'required': True,
        'readonly': True
    }
}
user_schema = {
    'username': {
        'type': 'string',
        'required': True,
        'unique': True,
    },
    'password': {
        'type': 'string',
        'required': True,
    },
    'token': {
        'type': 'string',
        'required': True,
    }
}

DOMAIN = {
    'user': {
        'schema': user_schema,
    },
    'note': {
        'schema': note_schema,
    },
}

auth 自带了根据用户名添加过滤器,过滤器的逻辑在这里很简单,但是你可以在过滤器中添加任何你想要的东西

class MyAuth(BasicAuth):
    def check_auth(self, token, allowed_roles, resource, method):
        username = get_username_from_token(token)
        if resource == 'note':
            note = app.config['DOMAIN']['note']
            user = app.data.driver.db['user'].find_one({'username': username})
            note['datasource']['filter'] = {'user_id': user['_id']}

        return True
于 2016-01-09T00:58:59.537 回答