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


Posted in Python onAugust 28, 2019

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

0x01. django认证系统

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

0x02. 认证系统User对象

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

username 
password 
email 
first_name 
last_name 
is_superuser 
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 %}

以上这篇django认证系统实现自定义权限管理的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python调用java的Webservice示例
Mar 10 Python
Python基于pygame实现图片代替鼠标移动效果
Nov 11 Python
Python的Flask框架及Nginx实现静态文件访问限制功能
Jun 27 Python
python使用tensorflow深度学习识别验证码
Apr 03 Python
python3中zip()函数使用详解
Jun 29 Python
对python requests的content和text方法的区别详解
Oct 11 Python
python 求某条线上特定x值或y值的点坐标方法
Jul 09 Python
python3应用windows api对后台程序窗口及桌面截图并保存的方法
Aug 27 Python
python从zip中删除指定后缀文件(推荐)
Dec 05 Python
pycharm安装及如何导入numpy
Apr 03 Python
Python3实现打印任意宽度的菱形代码
Apr 12 Python
基于python实现操作git过程代码解析
Jul 27 Python
Python中注释(多行注释和单行注释)的用法实例
Aug 28 #Python
对Django的restful用法详解(自带的增删改查)
Aug 28 #Python
Python closure闭包解释及其注意点详解
Aug 28 #Python
python opencv调用笔记本摄像头
Aug 28 #Python
Python threading的使用方法解析
Aug 28 #Python
Numpy对数组的操作:创建、变形(升降维等)、计算、取值、复制、分割、合并
Aug 28 #Python
Python logging设置和logger解析
Aug 28 #Python
You might like
一些星际专用术语解释
2020/03/04 星际争霸
将文件夹压缩成zip文件的php代码
2009/12/14 PHP
php获取从html表单传递数组的方法
2015/03/20 PHP
详谈php静态方法及普通方法的区别
2016/10/04 PHP
php redis实现文章发布系统(用户投票系统)
2017/03/04 PHP
php实现购物车功能(以大苹果购物网为例)
2017/03/09 PHP
php 数组元素快速去重
2017/05/05 PHP
基于jquery ajax 用户无刷新登录方法详解
2012/04/28 Javascript
jQuery简单图表peity.js使用示例
2014/05/02 Javascript
轻松实现javascript图片轮播特效
2016/01/13 Javascript
JS代码实现百度地图 画圆 删除标注
2016/10/12 Javascript
深入对Vue.js $watch方法的理解
2017/03/20 Javascript
静态页面实现 include 引入公用代码的示例
2017/09/25 Javascript
JS实现的将html转为pdf功能【基于浏览器端插件jsPDF】
2018/02/06 Javascript
详解vuex中action何时完成以及如何正确调用dispatch的思考
2019/01/21 Javascript
详解vue-property-decorator使用手册
2019/07/29 Javascript
详解vue-router 动态路由下子页面多页共活的解决方案
2019/12/22 Javascript
HTML元素拖拽功能实现的完整实例
2020/12/04 Javascript
Python编程实战之Oracle数据库操作示例
2017/06/21 Python
python 实现对文件夹内的文件排序编号
2018/04/12 Python
python制作抖音代码舞
2019/04/07 Python
PyQt5 对图片进行缩放的实例
2019/06/18 Python
python输出数组中指定元素的所有索引示例
2019/12/06 Python
Python getattr()函数使用方法代码实例
2020/08/10 Python
利用CSS3伪元素实现逐渐发光的方格边框
2017/05/07 HTML / CSS
美国在线印刷公司:PsPrint
2017/10/12 全球购物
美国领先的医疗警报服务:Philips Lifeline
2018/03/12 全球购物
德国高尔夫商店:Golfshop.de
2019/06/22 全球购物
意大利包包和行李箱销售网站:Bagaglio.it
2021/03/02 全球购物
一份Java笔试题
2012/02/21 面试题
行政专员岗位职责
2014/01/02 职场文书
人身意外保险授权委托书
2014/10/01 职场文书
黄山导游词
2015/01/31 职场文书
廉洁自律个人总结
2015/02/14 职场文书
圆明园观后感
2015/06/03 职场文书
担保书怎么写 ?
2019/04/22 职场文书