django认证系统实现自定义权限管理的方法


Posted in Python onJuly 16, 2018

本文记录使用django自带的认证系统实现自定义的权限管理系统,包含组权限、用户权限等实现。

0x01. django认证系统

django自带的认证系统能够很好的实现如登录、登出、创建用户、创建超级用户、修改密码等复杂操作,并且实现了用户组、组权限、用户权限等复杂结构,使用自带的认证系统就能帮助我们实现自定义的权限系统达到权限控制的目的。

0x02. 认证系统User对象

User对象顾名思义即为表示用户的对象,里面的属性包括:

  1. username
  2. password
  3. email
  4. first_name
  5. last_name
  6. is_superuser
  7. is_active

创建好对象后,django会自动生成表,表名为auth_user,包含以上字段。具体的api文档如下所示:

class models.User

User 对象具有如下字段:

username
必选。少于等于30个字符。 用户名可以包含字母、数字、_、@、+、.和- 字符。

first_name
可选。 少于等于30个字符。

last_name
可选。少于30个字符。

email
可选。邮箱地址。

password
必选。 密码的哈希及元数据。(Django 不保存原始密码)。原始密码可以无限长而且可以包含任意字符。参见密码相关的文档。

groups
与Group 之间的多对多关系。

user_permissions
与Permission 之间的多对多关系。

is_staff
布尔值。指示用户是否可以访问Admin 站点。

is_active
布尔值。指示用户的账号是否激活。

is_superuser
布尔值。只是这个用户拥有所有的权限而不需要给他们分配明确的权限。

last_login
用户最后一次登录的时间。

date_joined
账户创建的时间。当账号创建时,默认设置为当前的date/time。

一般在注册操作中会用到该方法,实现注册一个用户,用到的函数是User.objects.create_user(),在新建用户的时候需要判断用户是否存在,我的实现方式是,User.objects.get(username=xxx)去获取一个用户User对象,用try except实现,如果用户不存在则抛出User.DoesNotExist异常,在这个异常中进行创建用户的操作。具体代码如下:

# 注册操作
from django.contrib.auth.models import User

try:
 User.objects.get(username=username)
 data = {'code': '-7', 'info': u'用户已存在'}
except User.DoesNotExist:
 user = User.objects.create_user(username, email, password)
 if user is not None:
  user.is_active = False
  user.save()

该过程中密码字段会自动加密存储。无需关注过多细节。

0x03. 登录登出用户

创建好用户后,就是登录及登出了,django认证系统提供了login()logout()函数,能够自动登录登出,并且修改session值,非常方便。验证用户身份使用authenticate函数能自动进行password字段的hash比对。

具体实现代码如下:

from django.contrib.auth import authenticate, login, logout

# 认证操作
ca = Captcha(request)
if ca.validate(captcha_code):
 user = authenticate(username=username, password=password)
 if user is not None:
  if user.is_active:
   # 登录成功
   login(request, user) # 登录用户
   data = {'code': '1', 'info': u'登录成功', 'url': 'index'}
  else:
   data = {'code': '-5', 'info': u'用户未激活'}
 else:
   data = {'code': '-4', 'info': u'用户名或密码错误'}
else:
 data = {'code': '-6', 'info': u'验证码错误'}

登出操作如下:

from django.contrib.auth import authenticate, login, logout

def logout_system(request):
  """
  退出登录
  :param request:
  :return:
  """
  logout(request)
  return HttpResponseRedirect('/')

0x04. login_required装饰器

通过该装饰器能够使视图函数首先判断用户是否登录,如果未登录会跳到默认在settings.py设置的LOGIN_URL参数对应的url,如:LOGIN_URL = '/'。使用方法如下所示:

from django.contrib.auth.decorators import login_required

@login_required
def user_index(request):
  """
  用户管理首页
  :param request:
  :return:
  """
  if request.method == "GET":
    # 用户视图实现

0x05. 用户组及权限分配

组对象包含的字段只有name,但是外键了几张表,能够与user、permissions,产生多对多的关系,我在自定义权限实现中,采用的是权限写死的方法,添加用户组权限。

创建组的函数采用Group.objects.create(name=xxx),就能实现了。当然也跟创建用户一样,需要先判断是否组名已经存在。

创建好组名后,下一步就需要为每个组分配权限了,从前端提交过来的权限列表,然后后端采用groups.permissions.add(permission)的方式依次将权限添加进组。

添加完组权限后,最后一步是将组名添加进用户属性,区分用户属于哪个组。

具体实现代码如下:

# 创建组
try:
  Group.objects.get(name=role_name)
  data = {'code': -7, 'info': u'组名已存在'}
except Group.DoesNotExist:
  groups = Group.objects.create(name=role_name)
  if log_manage == 'true':
    permission = Permission.objects.get(codename='access_log')
    groups.permissions.add(permission)
  if role_manage == 'true':
    permission = Permission.objects.get(codename='access_role_manage')
    groups.permissions.add(permission)
  if user_manage == 'true':
    permission = Permission.objects.get(codename='access_user_manage')
    groups.permissions.add(permission)
  if get_users is not None:
    for user in get_users:
      # 每个user添加组属性
      db_user = get_object_or_404(User, username=user)
      db_user.groups.add(groups)
      data = {'code': 1, 'info': u'添加成功'}
  return HttpResponse(json.dumps(data))

0x06. 权限模型及权限控制

在上一点中用到的Permission.objects.get(codename='access_user_manage')是通过权限模型创建,需要在models中创建一个权限类,然后在meta中进行定义codename

class AccessControl(models.Model):
  """
  自定义权限控制
  """
  class Meta:
    permissions = (
      ('access_dashboard', u'控制面板'),
      ('access_log', u'日志管理'),
      ('access_role_manage', u'角色管理'),
      ('access_user_manage', u'用户管理'),
    )

运行后,会自动在数据库中创建相应的表,并且插入数据。

在创建好权限之后,下一步就是在各个视图中插入权限控制代码了。permission_required(),参数为当前应用名.codename。这样就能控制用户访问,如果用户非法访问则会清空session退出登录。

@permission_required('webcenter.access_role_manage')
@login_required
def role_index(request):
  """
  角色管理首页
  :param request:
  :return:
  """

同时在前端模板页面中也需要进行权限控制,前端要获取request对象的话,后端返回就需要使用render函数,render(request,xxx,xxx) ,具体代码就如下:

{% if request.user.is_superuser or 'webcenter.access_user_manage' in request.user.get_group_permissions or 'webcenter.access_role_manage' in request.user.get_group_permissions or 'webcenter.access_log' in request.user.get_group_permissions %}
<li class="treeview">
 <a href="#" rel="external nofollow" rel="external nofollow" >
   <i class="fa fa-fw fa-skyatlas"></i>
   <span>站点管理</span> <i class="fa fa-angle-left pull-right"></i>
 </a>
 <ul class="treeview-menu">
 {% if request.user.is_superuser or 'webcenter.access_log' in request.user.get_group_permissions %}
   <li><a href="#" rel="external nofollow" rel="external nofollow" id="log_view">日志管理</a></li>
 {% endif %}
 {% if request.user.is_superuser or 'webcenter.access_role_manage' in request.user.get_group_permissions %}
   <li><a href="/role/index/" rel="external nofollow" >角色管理</a></li>
 {% endif %}
 {% if request.user.is_superuser or 'webcenter.access_user_manage' in request.user.get_group_permissions %}
   <li><a href="/user/index/" rel="external nofollow" >用户管理</a></li>
 {% endif %}
</ul>
</li>
{% endif %}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python ORM框架SQLAlchemy学习笔记之安装和简单查询实例
Jun 10 Python
fastcgi文件读取漏洞之python扫描脚本
Apr 23 Python
python实时分析日志的一个小脚本分享
May 07 Python
Python编程之微信推送模板消息功能示例
Aug 21 Python
Python的CGIHTTPServer交互实现详解
Feb 08 Python
Django学习笔记之ORM基础教程
Mar 27 Python
python中多层嵌套列表的拆分方法
Jul 02 Python
新年快乐! python实现绚烂的烟花绽放效果
Jan 30 Python
python线程中的同步问题及解决方法
Aug 29 Python
django框架F&amp;Q 聚合与分组操作示例
Dec 12 Python
使用python操作lmdb对数据读取的实例
Dec 11 Python
如何在Python项目中引入日志
May 31 Python
Sanic框架路由用法实例分析
Jul 16 #Python
Sanic框架安装与简单入门示例
Jul 16 #Python
python 除法保留两位小数点的方法
Jul 16 #Python
Python自定义装饰器原理与用法实例分析
Jul 16 #Python
python 正确保留多位小数的实例
Jul 16 #Python
浅谈Python里面小数点精度的控制
Jul 16 #Python
详解Django中间件执行顺序
Jul 16 #Python
You might like
删除及到期域名的查看(抢域名必备哦)
2008/05/14 PHP
PHP树的深度编历生成迷宫及A*自动寻路算法实例分析
2015/03/10 PHP
jquery插件tytabs.jquery.min.js实现渐变TAB选项卡效果
2015/08/25 Javascript
JS提示:Uncaught SyntaxError: Unexpected token ILLEGAL错误的解决方法
2016/08/19 Javascript
详解探索 vuex 2.0 以及使用 vuejs 2.0 + vuex 2.0 构建记事本应用
2017/06/16 Javascript
vuex的简单使用教程
2018/02/02 Javascript
Vue.directive()的用法和实例详解
2018/03/04 Javascript
详解React Native 屏幕适配(炒鸡简单的方法)
2018/06/11 Javascript
vue模式history下在iis中配置流程
2019/04/17 Javascript
在Django的上下文中设置变量的方法
2015/07/20 Python
python开发之for循环操作实例详解
2015/11/12 Python
轻松掌握python设计模式之访问者模式
2016/11/18 Python
python实现图片转字符小工具
2019/04/30 Python
PyQt5的PyQtGraph实践系列3之实时数据更新绘制图形
2019/05/13 Python
Django框架封装外部函数示例
2019/05/28 Python
python 通过手机号识别出对应的微信性别(实例代码)
2019/12/22 Python
tensorflow通过模型文件,使用tensorboard查看其模型图Graph方式
2020/01/23 Python
python实现控制台输出彩色字体
2020/04/05 Python
python获得命令行输入的参数的两种方式
2020/11/02 Python
python+playwright微软自动化工具的使用
2021/02/02 Python
详解css3使用transform出现字体模糊的解决办法
2020/10/16 HTML / CSS
前端面试必备之html5的新特性
2017/09/05 HTML / CSS
英国轻奢珠宝品牌:Astley Clarke
2016/12/18 全球购物
Trina Turk官网:美国时装和泳装品牌
2018/06/10 全球购物
毕业生自荐信
2013/12/14 职场文书
大学生入党思想汇报
2014/01/01 职场文书
学生社团文化节开幕式主持词
2014/03/28 职场文书
初三开学计划书
2014/04/27 职场文书
新闻发布会策划方案
2014/06/12 职场文书
公司年底活动方案
2014/08/17 职场文书
党员对照检查材料整改措施思想汇报
2014/09/26 职场文书
专题组织生活会发言材料
2014/10/17 职场文书
2015年小学教师培训工作总结
2015/07/21 职场文书
《分数乘法》教学反思
2016/02/24 职场文书
Vue ECharts实现机舱座位选择展示功能
2022/05/15 Vue.js
python区块链持久化和命令行接口实现简版
2022/05/25 Python