我正在使用Eve構建REST API並使用角色來保護特定的端點,但除此之外,我還需要強制實施特定的字段級訪問規則。我有一個基本的users
端點以下模式:你如何在夏娃實施現場級安全?
users = {
'schema': {
Schema.NAME: {
'type': 'string',
'minlength': 1,
'maxlength': 32,
'required': True,
'unique': True
},
Schema.PASSWORD: {
'type': 'string',
'required': True
},
Schema.ROLE: {
'type': 'string',
'allowed': ['end user', 'manager', 'admin'],
'required': True
}
},
端點具有公共POST
訪問,所以任何人都可以創建一個用戶(即新用戶可以創建自己的帳戶)。最終用戶可以更改自己的密碼,管理員可以更改最終用戶的密碼,並且管理員可以更改最終用戶的角色。
我沒有看到用標準模式定義來做到這一點的方法。我還查看了Cerberus驗證,但似乎並未支持跨多個文檔的任何邏輯(即通過檢查客戶端是否被認證爲管理員user
來驗證最終用戶的user
文檔的修改)。
我實現我期待的效果通過添加事件掛鉤:
app.on_insert += all_users_created_equal
app.on_pre_PATCH_users += restrict_role_updates_to_admins
...
def all_users_created_equal(resource, docs):
"""Ensure that all users are created as end users.
Managers and Admins must be granted these roles by an existing
manager or admin."""
if resource == 'users':
for doc in docs:
doc['role'] = 'user'
def restrict_role_updates_to_admins(request, lookup):
if 'role' in request.json:
users = app.data.driver.db['users']
user = users.find_one({'name': request.authorization.username})
if user and user['role'] != 'admin':
# Non-admins cannot update roles. Break the lookup to fail the request.
lookup['_id'] = None
但它哈克以失敗請求與請求內容渣土。有沒有更好的方法來實施現場級安全?或者,如果沒有,是否有更好的方法來使用事件掛鉤來告訴服務器失敗請求?從鉤子引發異常的確會導致請求失敗,但異常會在服務器上傳播,並且不理想。
使請求失敗的更好方法是調用flask的中止函數。以下是文檔示例(http://flask.pocoo.org/docs/0.12/quickstart/#redirects-and-errors)。 – gcw