权限校验是确保应用程序安全的关键环节,装饰器在此处扮演着简化权限控制逻辑的角色。本章将探讨三种不同的权限验证策略,增强你的应用安全性。
5.1 基于角色的访问控制
基于角色的访问控制(Role-Based Access Control, RBAC)是常见的权限管理模型 ,通过定义角色并分配权限给角色 ,进而给用户分配角色来控制访问。
def role_required(role):
def decorator(func):
def wrapper(user, *args, **kwargs):
if user['role'] != role:
raise PermissionError("User does not have the required role.")
return func(user, *args, **kwargs)
return wrapper
return decorator
@role_required('admin')
def admin_only(user):
return f"Welcome, {user['name']}! You have admin privileges."
user = {'name': 'Alice', 'role': 'admin'}
print(admin_only(user)) # 正确执行
user = {'name': 'Bob', 'role': 'user'}
# print(admin_only(user)) # 将引发PermissionError
通过role_required装饰器,只有具备指定角色的用户才能执行被装饰的函数。
5.2 令牌验证装饰器
在API或Web应用中,令牌验证是常用的认证方式。下面的示例展示如何创建一个简单的JWT(JSON Web Token)验证装饰器。
import jwt
def jwt_required(token_secret):
def decorator(func):
def wrapper(token, *args, **kwargs):
try:
payload = jwt.decode(token, token_secret, algorithms=['HS256'])
except jwt.ExpiredSignatureError:
raise AuthenticationError("Token has expired.")
except jwt.InvalidTokenError:
raise AuthenticationError("Invalid token.")
return func(payload.get('user'), *args, **kwargs)
return wrapper
return decorator
@jwt_required('my_secret_key')
def protected_endpoint(token):
return f"Hello, {token['username']}! This is a protected endpoint."
# 注意:此处省略了实际生成和使用JWT的过程,仅演示装饰器的使用逻辑。
此装饰器确保请求携带有效的JWT ,并解码后传递用户信息给被装饰函数。
5.3 多重权限校验
在复杂场景中,可能需要同时校验多个权限条件。下面是一个多重权限检查的装饰器示例。
def multi_permission_check(checks):
def decorator(func):
def wrapper(*args, **kwargs):
for check in checks:
if not check(*args, **kwargs):
raise PermissionError("Permission check failed.")
return func(*args, **kwargs)
return wrapper
return decorator
def is_admin(user):
return user.get('role') == 'admin'
def is_owner(resource_id, user_id):
# 假设这是检查用户是否为资源所有者的逻辑
return True
@multi_permission_check([is_admin, lambda u: is_owner(u['resource_id'], u['id'])])
def delete_resource(user, resource_id):
return f"Resource {resource_id} deleted by {user['name']}."
# 测试用例
user = {'name': 'AdminUser', 'role': 'admin', 'id': 1, 'resource_id': 1}
print(delete_resource(user, 1)) # 成功执行
通过组合不同的权限检查函数,multi_permission_check装饰器确保所有条件都满足后才执行被装饰的函数,增加了权限控制的灵活性和安全性。