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

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 にアクセスできます。

2 つ目は、引き続き上のメソッドで、リクエストごとにデータソースのフィルターを更新することです。

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

これで、顧客は、指定されたエンドポイントで自分の「メモ」だけを見ることができます。

于 2014-03-18T11:28:45.100 に答える
1

リクエストごとにこれを行う方が良いかもしれないと思います。を変更する'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
于 2016-01-15T01:47:40.223 に答える
0

User-Restricted Resource Accessを調べましたか?

bills一見すると、ユーザー トークン (または ID、またはセットアップでユーザーを識別するもの) を請求書ドキュメントと共に保存し、エンドポイントで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,
    },
}

認証には、ユーザー名に基づいてフィルターを追加することが付属しています。フィルターのロジックはここでは単純ですが、フィルターに必要なものを追加できます

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 に答える