接口认证(实现不登陆不可以访问)
#helps.py中
class LoginRequiredAuthentication(BaseAuthentication):
def authenticate(self, request):
token = request.META.get('HTTP_TOKEN') #请求头中拿token
if token:
try:
payload = jwt.decode(token,SECRET_KEY)
user = payload['data']
return user,token #这里必须返回一个二元组
except DecodeError:
pass
raise AuthenticationFailed('请先登陆')
#视图集中views.py
@method_decorator(decorator=cache_page(timeout=1), name='list')
class EstateViewSet(ReadOnlyModelViewSet):
...
authentication_classes = (LoginRequiredAuthentication,) #认证类
...
(忽略以下代码)
访问控制(权限管理)
1.ACL(访问控制列表,Access Control List)-->访问白名单/访问黑名单
2.RBAC(基于角色的访问控制)
用户表 角色表 权限表 --> 多对多关系 (数据库中最少得5张表)
@lru_cache(maxsize=256) #缓存函数执行结果,自动清除最冷的键值对
class RbacPermission(BasePermission):
"""RBAC授权"""
# 返回True表示有操作权限,返回False表示没有操作权限
def has_permission(self, request, view):
'''简单来说如果能查询到这个权限,那就查询,如果不能那就返回json格式的错误信息'''
userid = request.user.get('userid')
user = User.objects.filter(userid=userid).first()
for role in user.roles.all():
for priv in role.privs.all():
if request.method == priv.method and request.path == priv.url:
return True
return False
#视图集中views.py
@method_decorator(decorator=cache_page(timeout=1), name='list')
class EstateViewSet(ReadOnlyModelViewSet):
...
authentication_classes = (LoginRequiredAuthentication,) #认证类
permission_classes = (RbacPermission,) #授权类
...
(忽略以下代码)
用户注销操作
def logout(request):
'''注销(销毁用户身份令牌)'''
#如果使用了JWT这种方式进行用户认证
#如何让令牌彻底失效??? ->Redis用集合类型做一个失效令牌清单(必须给过期时间或者定时任务清理过期令牌)
pass
其他:
from functools import lru_cache
@lru_cache() #如果没有这个装饰器,这个结果执行时间得很久很久,装饰器的用处就是不让做重复运算
def fib(num):
if num in (1,2):
return 1
return fib(num - 1) + fib(num - 2 )
for n in range(1,200):
print(f'{n}:{fib(n)}')