背景:网上看了一些django rbac的实现文章,感觉弄得比较麻烦,没有把django自带的那套权限管理利用起来。所以就自己写了一套。希望对大家帮助
思路:写一个权限类集成PermissionRequiredMixin,然后根据请求的方法和用户的权限做比较。判断是否拥有权限。例如 用户发送POST ,就判断用户是否对该对象有add 的权限。
优势:可以基于django用户管理快速实现rbac
缺点:颗粒度不够,无法限制到单个对象。
from rest_framework.serializers import ModelSerializer
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView
from demo.models import student
from django.contrib.auth import login, logout, authenticate
from django.views import View
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.http import request
class mylogin(View):
def post(self, request):
username = request.POST.get('username')
password = request.POST.get('password')
remember = request.POST.get('remember')
# 使用Django自带的authenticat()函数判断是否有该用户
user = authenticate(username=username, password=password)
# 如果存在该用户并且状态是激活的
print(user)
print(user.is_active)
if user and user.is_active:
# 使用Django的login()函数进行登陆
login(request, user)
# request.session['username'] = username
# 如果记住登陆,则使用全局的过期时间,默认为2周
if remember:
# 设置为None,则表示使用全局的过期时间
request.session.set_expiry(None)
else:
# 否则设为0,关掉浏览器就注销登陆状态了
request.session.set_expiry(0)
# 获取next页面(原本要访问的页面,因为没登陆所以转到login页面了),如果有的话则重定向到该页面
next_url = request.GET.get('next')
if next_url:
return redirect(next_url)
else:
return HttpResponse('登录成功')
else:
return HttpResponse('用户名或密码错误!')
class StudentSerializers(ModelSerializer):
class Meta:
model = student
fields = "__all__"
class mypermisson(PermissionRequiredMixin):
def has_permission(self):
appname = self.request.path.split("/")[1]
modelname = self.request.path.split("/")[2]
print(appname,modelname)
print(self.request.user)
method = self.request.method
user = self.request.user
if method == "GET":
return user.has_perm("{}.view_{}".format(appname,modelname))
elif method == "POST":
return user.has_perm("{}.add_{}".format(appname,modelname))
elif method == "DELETE":
return user.has_perm("{}.delete_{}".format(appname,modelname))
elif method == 'PUT':
return user.has_perm("{}.change_{}".format(appname,modelname))
else:
return False
class studentview(ListCreateAPIView):
permission_classes = [mypermisson]
queryset = student.objects.all()
serializer_class = StudentSerializers
def get(self, request, *args, **kwargs):
return self.list(request)
def post(self, request, *args, **kwargs):
return self.create(request)
class studentdetailview(RetrieveUpdateDestroyAPIView, mypermisson):
queryset = student.objects.all()
serializer_class = StudentSerializers
permission_classes = [mypermisson]
def get(self, request, pk):
return self.retrieve(request)
def post(self, request, pk):
return self.update(request)
def delete(self, request, pk):
return self.delete(request)