crm项目--rbac权限验证

rbac--基于角色的权限访问控制(Role-Based Access Control)

在crm系统中实现权限的控制管理基本实现

基本问题:

1. 什么是权限?
2. 为什么要有权限?
    不同用户拥有不同的功能 
3. 在web开发中,什么是权限?
    url 代表 权限

4. 开发一个权限的组件,为什么要开发组件?

5. 表结构的设计
    # 第一版
        权限表  permission
        id   url 
        
        用户表
        id  name  pwd 
        
        用户和权限的关系表
        id   user_id   permission_id  
        
    # 第二版
        权限表  permission
        id   url 
        
        角色表
        id  name
        
        角色和权限的关系表
        id  role_id  permission_id 
        
        用户表
        id  name  pwd
        
        用户和角色的关系表
        id   user_id   role_id 
        
总结:
    1. 权限控制
        1. 表结构的设计
            3个model  5张表
            权限表   url  title  
            角色表   name       多对多 permissions
            用户表   name  pwd  多对多 roles
            角色和权限的关系表 
            用户和角色的关系表 

        2. 流程:
            1. 登录
                get:通过中间件的白名单  re 获取到登录页面
                post: 
                    通过中间件的白名单
                    认证成功 保存权限信息
                        - ORM  去空的权限  去重 
                        - request.session  json序列化
            2. 免认证的访问
                判断登录状态
                获取免认证的地址 匹配  re
                
            3. 需要的校验的地址
                - 中间件
                    从session中获取到当前用户的权限信息
                    循序权限信息 和 当前的url 匹配
                    
                    匹配成功  return 正常流程
                    所有都匹配不成功  没有权限  return HttpResponse('没有访问的权限') 

 

实现权限管理,要从表结构开始入手,上面是五张表的设计,在django中实现写三个model,其中两个多对多关系,一共五张表.通过对不同的用户分配不同的角色, 不同的角色对应不同的权限来实现需求

 models中想在前端显示对象的中文,在admin.py中

from django.contrib import admin
from rbac import models

# Register your models here.
# class PermissionAdmin(admin.ModelAdmin):
class PermissionAdmin(admin.ModelAdmin):
    list_display = ['url','title']
    list_editable = ['title']



class UserAdmin(admin.ModelAdmin):
    list_display = ['name',]


admin.site.register(models.Permission,PermissionAdmin)
admin.site.register(models.Role,UserAdmin)
admin.site.register(models.User)

 

注意数据中的数据url填写

 

 models

from django.db import models


class Permission(models.Model):
    """
    权限表
    """
    url = models.CharField('权限', max_length=32)
    title = models.CharField('标题', max_length=32)

    def __str__(self):
        return self.title


class Role(models.Model):
    """
    角色表
    """
    name = models.CharField('角色名称', max_length=32)
    permissions = models.ManyToManyField('Permission', verbose_name='角色所拥有的权限', blank=True)

    def __str__(self):
        return self.name


class User(models.Model):
    """
    用户表
    """
    name = models.CharField('用户名', max_length=32)
    pwd = models.CharField('密码', max_length=32)
    roles = models.ManyToManyField('Role', verbose_name='用户所拥有的角色', blank=True)

    def __str__(self):
        return self.name

urls.py

from django.conf.urls import url
from web.views import customer
from web.views import payment
from web.views import auth

urlpatterns = [

    url(r'^login/$', auth.login, name='login'),
    url(r'^index/$', auth.index, name='index'),

    url(r'^customer/list/$', customer.customer_list),
    url(r'^customer/add/$', customer.customer_add),
    url(r'^customer/edit/(?P<cid>\d+)/$', customer.customer_edit),
    url(r'^customer/del/(?P<cid>\d+)/$', customer.customer_del),

    url(r'^payment/list/$', payment.payment_list),
    url(r'^payment/add/$', payment.payment_add),
    url(r'^payment/edit/(?P<pid>\d+)/$', payment.payment_edit),
    url(r'^payment/del/(?P<pid>\d+)/$', payment.payment_del),
]

中间件,记得去settiings中注册,需要用到自己在settings中的配置

settings

WHITE_LIST = [
    r'^/login/$',
    r'^/reg/$',
    r'^/admin/.*',
]

NO_PERMISSION_LIST = [
    r'^/index/$',
]

middlware/auth.py

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse, redirect, reverse
from django.conf import settings
import re
class RbacMiddleWare(MiddlewareMixin): def process_request(self, request): # 获取当前访问的页面 url = request.path_info # index # 白名单 for i in settings.WHITE_LIST: if re.match(i, url): return # 获取登录状态 is_login = request.session.get('is_login') # 没有登录跳转到登录页面 if not is_login: return redirect(reverse('login')) # 免认证 for i in settings.NO_PERMISSION_LIST: if re.match(i, url): return # 获取当前用户的权限 permission_list = request.session['permission'] print(permission_list) # 权限的校验 for i in permission_list: if re.match('^{}$'.format(i['permissions__url']), url): return # 没匹配成功 没有权限 return HttpResponse('没有访问的权限')

views.py

from django.shortcuts import reverse, redirect, render
from rbac import models


def login(request):
    if request.method == 'POST':

        username = request.POST.get('username')
        password = request.POST.get('password')

        obj = models.User.objects.filter(name=username, pwd=password).first()

        if obj:

            permissions = obj.roles.filter(permissions__isnull=False).values('permissions__url', 'permissions__title')

            # permissions = obj.roles.values('permissions__url', 'permissions__title')
            print(permissions)
            # 设置权限
            request.session['permissions'] = list(permissions)

            # 设置登陆状态
            request.session['is_login'] = True

            return redirect('index')
        else:
            return render(request, 'login.html', {'errors': '用户名或密码错误'})

    return render(request, 'login.html')


def index(request):
    return render(request, 'index.html')

 

posted @ 2019-03-19 20:23  robertx  阅读(629)  评论(0)    收藏  举报