DRF permission control

  • Prerequisite: There is a user type field in the user table
Define permission control classes
  • Define permission control classes for Admin and VIP users
    from rest_framework import exceptions
    from app01 import models
    from rest_framework.permissions import BasePermission
    class AdminUserpermission(Basepermission) :
            # Change the returned error message to the message you want to display
            massage = 'You don't have permission! '
            # Notice that the method name is fixed
            def has_permission(self, request, view) :
            user_type = request.user.user_type
            if user_type == 2:
                    # return True to validate
                return True
            else:
                    # return False to indicate that validation failed
                return False
    
    class VIPUserpermission(Basepermission) :
            # Change the returned error message to the message you want to display
            massage = 'You don't have permission! '
            # Notice that the method name is fixed
            def has_permission(self, request, view) :
            user_type = request.user.user_type
            if user_type == 1:
                    # return True to validate
                return True
            else:
                    # return False to indicate that validation failed
                return False
    Copy the code
Use permission control classes
  • Use the defined permission control classes in the view
The global
  • In Setting
    REST_FRAMEWORK = {
        'DEFAULT_PERMISSION_CLASSES': ['VIPUserPermission']}Copy the code
    • Generally, the lowest level of permission is used globally, and the local level can be overridden if a higher level of permission is needed
  • Accessing the Books view
    class Books(APIView) :
    [root@localhost] [root@localhost] [root@localhost
    def get(self, request) :
        books = models.Book.objects.all()
        books_res = BooksDRF(books, many=True)
        authors = models.Author.objects.all()
        authors_res = AuthorsDRF(instance=authors,many=True)
        response = {'status':200.'msg':'Query successful! '.'books':books_res.data,'authors':authors_res.data}
        return JsonResponse(response, safe=False)
    Copy the code
Local use
  • Local users can use their own permissions to override global permissions
    class UserInfo(APIView) :
    AdminUserpermission Is required for partial rewrite permission
    permission_classes = [AdminUserpermission, ]
    def get(self, request) :
        userInfos = models.User.objects.all()
        userInfos_res = UserInfoDRF(books, many=True)
        response = {'status':200.'msg':'Query successful! '.'userInfos':userInfos_res.data}
        return JsonResponse(response, safe=False)
    Copy the code

Vue background management permission control

  • User type: Super administrator admin; Common editor user Editor
Implementation steps
  1. The VUe-Router is mounted when the Vue instance is created, but the Vue-Router mounts some public pages for login or non-permission purposes
  2. Router.js (router.js) uses meta tags to indicate the access permissions for routing (pages), for example:meta: { role: ['admin','editor'] }Indicates that the page is accessible only to admin and Editor
  • Configure the route access permission
    // router.js
    import Vue from 'vue'
    import Router from 'vue-router'
    
    Vue.use(Router)
    
    export const constantRouterMap = [
      {
        path: '/'.redirect: '/login'.hidden: true
      },
      {
        path: '/login'.name: 'Login page'.hidden: true.component: resolve= > require(['.. /views/login/Login.vue'], resolve)
      },
      {
        path: '/Readme'.// name: 'Readmehome',
        index: 'Readme'.meta: {
          title: 'Readme'.icon: 'el-icon-menu'
        },
        component: resolve= > require(['.. /components/common/Home.vue'], resolve),
        children: [{name: 'Readme'.path: '/'.meta: { title: 'Readme'.icon: 'el-icon-menu' },
            component: resolve= > require(['.. /components/page/Readme.vue'], resolve)
          }
        ]
      }
    ]
    
    export default new Router({
      routes: constantRouterMap
    })
    // Asynchronously mounted route
    // Dynamic routing tables that need to be loaded according to permissions
    export const asyncRouterMap = [
      {
        path: '/permission'.// name: 'permissionhome',
        meta: {
          title: 'permission'.icon: 'el-icon-setting'.roles: ['admin']},component: resolve= > require(['.. /components/common/Home.vue'], resolve),
        children: [{name: 'permission'.path: '/permission'.meta: {
              title: 'permission'.icon: 'el-icon-menu'.roles: ['admin']},component: resolve= > require(['.. /components/page/permission.vue'], resolve)
          }
        ]
      },
      { path: The '*'.redirect: '/ 404'.hidden: true}]Copy the code
  • Special instructions
    • One important thing to note here is that 404 pages must be loaded last. If a 404 is declared with a constant troutermap, all subsequent pages will be blocked to 404
  1. When the user logs in, the role is obtained
  2. To compare roles with the required permissions for each page of the routing tablerouter.addRoutes(store.getters.addRouters)Add routes accessible to users, generate a routing table accessible to end users, and save the routing table in the VUEX
  • permission.js
    // permission.js
    import router from './router'
    import store from './store'
    import { Message } from 'element-ui'
    import { getToken } from '@/utils/auth' / / check
    
    const whiteList = ['/login'.'/authredirect'] // Do not redirect the whitelist
    
    router.beforeEach((to, from, next) = > {
      if (getToken()) { // Check whether there is a token
        if (to.path === '/login') {
          next({ path: '/'})}else {
          if (store.getters.roles.length === 0) {
            console.log('roles====0')
            store.dispatch('GetInfo').then(res= > { // Pull user information
              const roles = res.data.roles // note: roles must be a array! such as: ['editor','develop']
              console.log('roles? ', roles)
              store.dispatch('GenerateRoutes', { roles }).then(() = > { // Generate an accessible routing table based on roles permissions
                console.log('addrouters', store.getters.addRouters)
                router.addRoutes(store.getters.addRouters) // Dynamically add the accessible routing tablenext({ ... to,replace: true }) // the hack method ensures that addRoutes is complete,set the replace: true so the navigation will not leave a history record
              })
            }).catch(() = > {
              store.dispatch('FedLogOut').then(() = > {
                Message.error('Authentication failed, please log in again')
                next({ path: '/login'})})})}else {
            console.log('= = = = 1')
            next() // If the user has permission, all accessible routes have been generated. If the user does not have permission to access all routes, the 404 page will be displayed automatically}}}else {
        if(whiteList.indexOf(to.path) ! = = -1) {
          next()
        } else {
          next('/login')}}})Copy the code
  1. Render sidebar components based on accessible routes in VUEX:<v-sidebar :routers="routers"></v-sidebar>
  • Use the navigation bar on the required page
    <template>
        <div class="wrapper">
            <v-head></v-head>
            <! -- Loop the routing information stored in vuEX -->
            <v-sidebar :routes="routes"x</v-sidebar>
            <div class="content">
                 <transition name="move" mode="out-in"><router-view></router-view</transition>
            </div>
        </div>
    </template>
    Copy the code
  1. Create the left navigation bar component Sidebar
  • The navigation page is created dynamically using ElementUI’s left navigation component and dynamically generated data from Vuex

Reference and thanks

  • DRF permission control
  • Background system authority control based on Vue