当前位置: 代码迷 >> python >> Python-eve RestApi框架中的用户依赖资源筛选器
  详细解决方案

Python-eve RestApi框架中的用户依赖资源筛选器

热度:88   发布时间:2023-06-19 09:21:43.0

我想基于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会做。 请参阅 。

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

更新

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

那呢?

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

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

多亏了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'] }

现在,客户在给定的端点上只能看到自己的“注释”。

我认为最好根据每个请求执行此操作。 修改'DOMAIN'可能会导致以下情况:多个人同时登录并发送请求,并且请求之间的域更改取决于您实施此类操作的方式。 也许这样的事情会工作:

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

您是否浏览过 ?

乍一看,我想说是通过将用户令牌(或ID,或在您的设置中标识用户的任何内容)与帐单文档一起存储,然后在bills端点启用URRA,可以解决问题。

更加完整的示例如下,假设我们在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
  相关解决方案