1 RABC权限管理
1.1 表关系分析
1.2 表设计
1.2.1 用户表
账号、姓名、邮箱、添加时间、最后登录时间、账号是否禁止登录
1.2.2 角色表
商品管理员、订单管理员、超级管理员
1.2.3 资源列表
储存是路径正则
资源分类:商品模块、订单模块、营销模块、权限模块、内容模块、其他模块
1.2.4 权限表
对某一个路由的增删改查
# 源码分析
class BasePermission(metaclass=BasePermissionMetaclass):
"""
A base class from which all permission classes should inherit.
"""
def has_permission(self, request, view):
# has_permission 是用户对这个视图有没有 GET POST PUT PATCH DELETE 权限的分别判断
"""
Return `True` if permission is granted, `False` otherwise.
"""
return True
def has_object_permission(self, request, view, obj):
# 判断当前用户是否有访问某个接口的接口权限
"""
Return `True` if permission is granted, `False` otherwise.
"""
return True
1.3 具体分析
1.3.1 如果只允许post方法访问
- utils/Authentication.py
class MyPermission(BasePermission):
# 继承的一定要是rest_framework里面的BasePermission,类的名字随意
# has_permission 是用户对这个视图有没有 GET POST PUT PATCH DELETE 权限的分别判断
def has_permission(self, request, view):
# 可以用request.user来获取用户名
# 可以用request.method来查询访问的方式
# 可以用request.path_info来查询访问的路由
# 可以用 print(dir(request))来查看方法
# 任何用户对使用此权限类的视图都有访问权限
if request.method == 'post':
print(request.method)
if request.user.is_superuser:
return True
elif view.kwags.get('pk') == str(request.user.id):
return True
return False
# 访问的是get方法,所以直接走了False,不会执行下面的has_object_permission方法了!!!
# has_object_permission 是用户过了 has_permission 判断有权限以后,再判断这个用户有 没有对一个具体的对象有没有操作权限
# 这样设置以后,即使是django admin管理员也只能查询自己user标的信息,不能查询其他用户的 单条信息
def has_object_permission(self, request, view,obj):
# 判断当前用户是否有访问 /course/sections/1/ 接口权限
course_detail_url = re.match('/course/sections/(d+)/$', request.path_info)
if course_detail_url:
user = request.user
course = obj.chapters.course
has_video_rights = self.video_rights(user,course)
return has_video_rights
return True
# 对用户是否有课程播放权限进行验证
@staticmethod
def video_rights(user,course):
'''
:param user: 当前登录用户
:param course: 用户要播放的课程对象
:return: 返回True有权限,否则出发异常
'''
# 1.免费课程直接返回True
# 2.会员免费课程,判断当前用户是否是会员,如果是会员返回True
# 3.付费课程,判断当前用户在UserCourse表中有购买记录返回True
try:
is_buy = UserCourse.objects.get(course=course, user=user)
return True
except Exception as e:
raise exceptions.ParseError('没卖课程播放个毛线!头给你打扁!')
- views.py
from Authentication import MyPermission
from rest_framework import viewsets
class SectionsViewSet(viewsets.ModelViewSet):
queryset = Sections.objects.all()
serializer_class = SectionsSerializer
permission_classes = (MyPermission, )
- postman效果
http://192.168.56.100:8888/course/sections/3/?id=3
1.3.2 允许get访问
- utils/Authentication.py
- 第一个方法has_permission()整体跑通
# -*- coding: utf-8 -*-
import re
from rest_framework.permissions import BasePermission
from rest_framework import exceptions
from course.models import UserCourse
class MyPermission(BasePermission):
# 继承的一定要是rest_framework里面的BasePermission,类的名字随意
# has_permission 是用户对这个视图有没有 GET POST PUT PATCH DELETE 权限的分别判断
def has_permission(self, request, view):
print(dir(request))
print(request.method)
print(request.user)
# 可以用request.user来获取用户名
# 可以用request.method来查询访问的方式
# 可以用request.path_info来查询访问的路由
# 可以用 print(dir(request))来查看方法
# 任何用户对使用此权限类的视图都有访问权限
if request.method == 'GET':
if request.user.is_superuser:
return True
elif view.kwargs.get('pk') == str(request.user.id):
return True
return False
# has_object_permission 是用户过了 has_permission 判断有权限以后,再判断这个用户有 没有对一个具体的对象有没有操作权限
# 这样设置以后,即使是django admin管理员也只能查询自己user标的信息,不能查询其他用户的 单条信息
def has_object_permission(self, request, view,obj):
return True
- views.py
from Authentication import MyPermission
from rest_framework import viewsets
class SectionsViewSet(viewsets.ModelViewSet):
queryset = Sections.objects.all()
serializer_class = SectionsSerializer
permission_classes = (MyPermission, )
- postman效果
http://192.168.56.100:8888/course/sections/3/?id=3
1.3.3 没有购买订单
- models.py
# -*- coding: utf-8 -*-
import re
from rest_framework.permissions import BasePermission
from rest_framework import exceptions
from course.models import UserCourse
class MyPermission(BasePermission):
# 继承的一定要是rest_framework里面的BasePermission,类的名字随意
# has_permission 是用户对这个视图有没有 GET POST PUT PATCH DELETE 权限的分别判断
def has_permission(self, request, view):
print(dir(request))
print(request.method)
print(request.user)
# 可以用request.user来获取用户名
# 可以用request.method来查询访问的方式
# 可以用request.path_info来查询访问的路由
# 可以用 print(dir(request))来查看方法
# 任何用户对使用此权限类的视图都有访问权限
if request.method == 'GET':
if request.user.is_superuser:
return True
elif view.kwargs.get('pk') == str(request.user.id):
return True
return False
# has_object_permission 是用户过了 has_permission 判断有权限以后,再判断这个用户有 没有对一个具体的对象有没有操作权限
# 这样设置以后,即使是django admin管理员也只能查询自己user标的信息,不能查询其他用户的 单条信息
def has_object_permission(self, request, view,obj):
# 判断当前用户是否有访问 /course/sections/1/ 接口权限
course_detail_url = re.match('/course/sections/(d+)/$', request.path_info)
if course_detail_url:
user = request.user
course = obj.chapters.course
has_video_rights = self.video_rights(user,course)
return has_video_rights
return True
# 对用户是否有课程播放权限进行验证
@staticmethod
def video_rights(user,course):
'''
:param user: 当前登录用户
:param course: 用户要播放的课程对象
:return: 返回True有权限,否则出发异常
'''
# 1.免费课程直接返回True
# 2.会员免费课程,判断当前用户是否是会员,如果是会员返回True
# 3.付费课程,判断当前用户在UserCourse表中有购买记录返回True
try:
is_buy = UserCourse.objects.get(course=course, user=user)
return True
except Exception as e:
raise exceptions.ParseError('没买课程播放个毛线!头给你打扁!')
- views.py
from Authentication import MyPermission
from rest_framework import viewsets
class SectionsViewSet(viewsets.ModelViewSet):
queryset = Sections.objects.all()
serializer_class = SectionsSerializer
permission_classes = (MyPermission, )
- 第二个方法中由于数据库中没有数据,所以会走False
- 显示没有购买,没办法观看
http://192.168.56.100:8888/course/sections/3/?id=3
1.3.4 购买才能访问
- models.py
# -*- coding: utf-8 -*-
import re
from rest_framework.permissions import BasePermission
from rest_framework import exceptions
from course.models import UserCourse
class MyPermission(BasePermission):
# 继承的一定要是rest_framework里面的BasePermission,类的名字随意
# has_permission 是用户对这个视图有没有 GET POST PUT PATCH DELETE 权限的分别判断
def has_permission(self, request, view):
print(dir(request))
print(request.method)
print(request.user)
# 可以用request.user来获取用户名
# 可以用request.method来查询访问的方式
# 可以用request.path_info来查询访问的路由
# 可以用 print(dir(request))来查看方法
# 任何用户对使用此权限类的视图都有访问权限
if request.method == 'GET':
if request.user.is_superuser:
return True
elif view.kwargs.get('pk') == str(request.user.id):
return True
return False
# has_object_permission 是用户过了 has_permission 判断有权限以后,再判断这个用户有 没有对一个具体的对象有没有操作权限
# 这样设置以后,即使是django admin管理员也只能查询自己user标的信息,不能查询其他用户的 单条信息
def has_object_permission(self, request, view,obj):
# 判断当前用户是否有访问 /course/sections/1/ 接口权限
course_detail_url = re.match('/course/sections/(d+)/$', request.path_info)
if course_detail_url:
user = request.user
course = obj.chapters.course
has_video_rights = self.video_rights(user,course)
return has_video_rights
return True
# 对用户是否有课程播放权限进行验证
@staticmethod
def video_rights(user,course):
'''
:param user: 当前登录用户
:param course: 用户要播放的课程对象
:return: 返回True有权限,否则出发异常
'''
# 1.免费课程直接返回True
# 2.会员免费课程,判断当前用户是否是会员,如果是会员返回True
# 3.付费课程,判断当前用户在UserCourse表中有购买记录返回True
try:
is_buy = UserCourse.objects.get(course=course, user=user)
return True
except Exception as e:
raise exceptions.ParseError('没买课程播放个毛线!头给你打扁!')
- views.py
from Authentication import MyPermission
from rest_framework import viewsets
class SectionsViewSet(viewsets.ModelViewSet):
queryset = Sections.objects.all()
serializer_class = SectionsSerializer
permission_classes = (MyPermission, )
- 数据库中有数据
- postman演示
1.4 踩坑点
# 常用问题:
一定要注意,在用postman调试过程中,访问视图的时候,headers中加入token,格式是:
Authorization:JWT token(中间有空格)
不然会获取不到用户哦~