django自带的用户认证系统提供了访问控制的的功能。
 
1.只允许登录的用户登录
 
django的用户可分为两类,一是可认证的用户,也就是在django.contrib.auth.models.User中注册了的;另一种是匿名用户django.contrib.auth.models.AnonymousUser,每个访问的未登录的用户都是该类的一个实例,而匿名用户是无法认证的,即 is_authenticated 方法永远返回 False,或者is_anonymous返回True,我们可以在代码逻辑中实现对匿名用户进行判断,然后拒绝其访问(403),或者重定向到登录页面等。
 
  1. from django.conf import settings
  2. from django.shortcuts import redirect
  3.  
  4. def my_view(request):
  5. if not request.user.is_authenticated:
  6. return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
  7. # ...
以上就是在代码中重定向到登录页面的做法,也可以返回错误信息:
 
  1. from django.shortcuts import render
  2.  
  3. def my_view(request):
  4. if not request.user.is_authenticated:
  5. return render(request, 'myapp/login_error.html')
  6. # ...
由于这是一个常见的需求,所以django提供了一个装饰器来实现这个功能。
 
  1. from django.contrib.auth.decorators import login_required
  2.  
  3. @login_required
  4. def my_view(request):
  5. ...
 
这样大大的简化了工作。
 
 login_required(redirect_field_name='next', login_url=None) 
 
若用户没有登录的话, 其将无法访问被装饰的视图,而是重定向到登录页面,这个登录页面可以使用login_url参数指定,并且可以接受命名url的方式,如:@login_required(login_url='login'),当然前提是要有相应的命名的url。如果没有给定这个参数,将使用settings.LOGIN_URL的值。
 
 
LOGIN_URL
Default: '/accounts/login/'
 
The URL where requests are redirected for login, especially when using the login_required() decorator.
 
This setting also accepts named URL patterns which can be used to reduce configuration duplication since you don’t have to define the URL in two places (settings and URLconf).
 
可以看见其有默认值,如果你不给参数,且登录地址不是这个默认值,将触发404错误,也就是还是重定向到那个页面去了,只是找不到而已。若强制重写为None,其会触发TypeError,若DEBUG=False,则应该是500系列的服务器错误。
 
但是,在重定向的时候,并不是单纯跳转,而是会带一个next查询参数例如:
 
 
 
这样你就可以获取登录前想要访问的页面(这里就是/account/change_info页面了),然后在登录后重定向回去,而不用盲目重定向到首页,用户体验会更好点。
 
下面就是登录视图中所做的配合:
 
  1. next_to = request.GET.get('next', None) # 获取是否有next的重定向,是一个相对路径,不含方案和域名
  2. if next_to:
  3. return redirect(next_to)
当然你也可以改变redirect_field_name来改变next这个名称,当然在登录视图里也要做想要的调整,也可以将其设为None来取消附带参数的行为。
 
 
注意:login_required 并不会检查用户是否处于活跃状态(is_active),而处理用户登录的默认后台模板在1.10之前并不会拒绝非活跃用户登录,而1.10版本就会。这意味着如果你使用的版本低于1.10,你必须在代码逻辑中拒绝非活跃用户登录。
 
  1. if user.is_active: # 若用户是活跃的,即未冻结的,在1.10之前冻结用户默认也能登录,所以需要自己认证
  2. login(request, user) # 登录
  3. ...... #其他处理
  4. else:
  5. return HttpResponse('用户被冻结')
 

2.只允许staff身份的用户访问某个视图
 
django同样提供了一个便捷的装饰器来实现这个功能:
 
 staff_member_required(redirect_field_name='next', login_url='admin:login') 
 
 
可以看到其和上述的 login_required 参数上几乎一样,只是默认值有些许不同,而在用法上也是一样的,但并没有settings.LOGIN_URL之类的设置层面上的退路。要注意一点,因为其默认是重定向至admin的登录页面,若要通过复杂化url的方式来隐藏入口的时候,要小心其会暴露该url。
 
This decorator is used on the admin views that require authorization. A view decorated with this function will having the following behavior:
这个装饰器已经被admin的视图所使用了,其行为如下:
 
 
 
  • If the user is logged in, is a staff member (User.is_staff=True), and is active (User.is_active=True), execute the view normally.
如果用户已经登录,且为staff身份,并且是活跃的,则正常执行所装饰的视图。
 
  • Otherwise, the request will be redirected to the URL specified by the login_url parameter, with the originally requested path in a query string variable specified by redirect_field_name. For example: /admin/login/?next=/admin/polls/question/3/.
否则,将会重定向到login_url,并带查询参数。
 
Example usage:
用例:
 
 
  1. from django.contrib.admin.views.decorators import staff_member_required
  2.  
  3. @staff_member_required
  4. def my_view(request):
  5. ...
可以看到其使用方法和login_required()基本是一样的。
 

3.简单的函数测试验证法
 
django提供了一个装饰器,让我们可以自定义一个简单的验证函数,只有通过该验证函数之后才能访问指定的视图。
 
 user_passes_test(func[, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME]) 
 
可以看到其比上面的两个装饰器多了一个参数,这个参数就是用指定验证函数的。
 
例如,我想要验证某个用户的邮箱是否符合我想要的格式:
 
原始的验证法:
 
  1. from django.shortcuts import redirect
  2.  
  3. def my_view(request):
  4. if not request.user.email.endswith('@example.com'):
  5. return redirect('/login/?next=%s' % request.path)
  6. # ...
 
在视图函数中验证其是否以@example.com结尾。
 
下面是装饰器验证法:
 
  1. from django.contrib.auth.decorators import user_passes_test
  2.  
  3. def email_check(user):
  4. return user.email.endswith('@example.com')
  5.  
  6. @user_passes_test(email_check)
  7. def my_view(request):
  8. ...
注意:email_check函数其本质上也是返回布尔值,所以在自定义函数的时候,返回True表示通过,False表示不通过。不通过则重定向到登录页面,其他细节和之前的两个装饰器一样。
 
 

基于类的视图的实现
 
基于类的视图在实现login_required的行为时,需要继承LoginRequiredMixin这个类,并将其放在继承树的最左边,同时相应的实现在类中书写,例如:
 
  1. from django.contrib.auth.mixins import LoginRequiredMixin
  2.  
  3. class MyView(LoginRequiredMixin, View):
  4. login_url = '/login/'
  5. redirect_field_name = 'redirect_to'
 
注:这里是View是通用视图,这里并没要导入的代码,详情请参考基于类的视图。
 
还有更多的属性可供使用,可参考 AccessMixin 这个类。
 
 
实现user_passes_test行为也是类似的,首先继承UserPassesTestMixin这个类(在最左边),然后在类的里面重写test_func方法,该方法也是返回布尔值。
 
New in Django 1.9.
 
  1. from django.contrib.auth.mixins import UserPassesTestMixin
  2.  
  3. class MyView(UserPassesTestMixin, View):
  4.  
  5. def test_func(self):
  6. return self.request.user.email.endswith('@example.com')
注:上述的两个也是不验证是否为活跃用户的,所以使用的时候要小心。
 
 
 
 
 
 
 
 
 
 

django-访问控制的更多相关文章

  1. [Django REST framework - RBAC-基于角色的访问控制、base64编码 、xadmin的使用]

    [Django REST framework - RBAC-基于角色的访问控制.base64编码 .xadmin的使用] RBAC-基于角色的访问控制 RBAC 是基于角色的访问控制(Role-Bas ...

  2. 用Django写出“hell world”

    一.系统实战环境 1 2 3 4 系统版本:CnetOS6.5 x86_64 Django版本:Django-1.5.8 MySQL版本:MySQL-5.1.73 Python版本: python-2 ...

  3. django中post方法和get方法的不同

    当我们提交表单仅仅需要获取数据时就可以用GET: 而当我们提交表单时需要更改服务器数据的状态,或者说发送e-mail,或者其他不仅仅是获取并显示数据的时候就使用POST. 在这个搜索书籍的例子里,我们 ...

  4. Django用户认证系统(一)User对象

    User对象 User对象是认证系统的核心.用户对象通常用来代表网站的用户,并支持例如访问控制.注册用户.关联创建者和内容等.在Django认证框架中只有一个用户类,例如超级用户('superuser ...

  5. ubuntu下配置Apache+mod_wsgi+Django项目(个人测试)

    经过了一个星期的摸索,查找资料以及实验,我搭建的环境基本能用(还有就是Django后台的静态文件加载的问题) 这里面只是介绍一下我的过程,因为对应Apache还不是很熟练,特别是配置文件.只能供大家参 ...

  6. 【Django】 rest-framework和RestfulAPI的设计

    [rest-framework] 这是一个基于django才能发挥作用的组件,专门用于构造API的. 说到API,之前在其他项目中我也做过一些小API,不过那些都是玩票性质,结构十分简单而且要求的设计 ...

  7. 【django之权限组件】

    一.需求分析 RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联.简单地说,一个用户拥有若干角色,一个角色拥有若干权限.这样,就构造成& ...

  8. Django生命周期 URL ----> CBV 源码解析-------------- 及rest_framework APIView 源码流程解析

    一.一个请求来到Django 的生命周期   FBV 不讨论 CBV: 请求被代理转发到uwsgi: 开始Django的流程: 首先经过中间件process_request (session等) 然后 ...

  9. django restframework 跨域访问

    场景介绍: 在Django开发过程中,使用前后端分离设计的站点越来越多,如Django+VUE.Django+Angular.在使用DjangoRestFramework开发API的过程中,由于前端站 ...

  10. django项目实际工作中的配置以及一些有用的小工具(持续更新)

    常用pycharm快捷键:   https://www.cnblogs.com/luolizhi/p/5610123.html   Ctrl + F1  显示错误 Ctrl + Alt + Space ...

随机推荐

  1. linux 下安装 oracle

    http://yourcouner.blog.51cto.com/59520/91156 一.RedHat AS4系统安装: 磁盘配置: 设备 类型 大小 / ext3 39911 swap 1024 ...

  2. SpringMVC集成MongoDb

    (1)pom添加相关依赖 <dependency> <groupId>org.springframework.data</groupId> <artifact ...

  3. IAR拷贝工程后,修改工程名的方法

    在实际使用过程中,经常基于某个demo进行开发,但是demo的项目名往往不满足新项目的名称,如果重新建立工程,就需要进行一系列的配置,非常麻烦,其实可以直接修改项目名,做法如下; 1. 修改项目目录下 ...

  4. Linux input子系统简介

    1.前言 本文主要对Linux下的input子系统进行介绍 2. 软件架构 图 input子系统结构图 input子系统主要包括三个部分:设备驱动层.核心层和事件层.我们可以分别理解为:具体的输入设备 ...

  5. oracle 监听 添加ip

    同时修改tnsnames.ora.listener.ora将这两个文件中HOST后面的主机都修改为127.0.0.1然后重启OracleServiceXE.OracleXETNSListener服务 ...

  6. 源码编译安装mysql5.5.33

    源码编译安装mysql5.5.33 一.安装cmake编译工具 跨平台编译器 # yum install -y gcc* # yum install -y cmake 解决依赖关系 # yum ins ...

  7. css之hover改变子元素和其他元素样式

    参考地址:链接 +表示下一级元素,>表示子元素 <!DOCTYPE html> <html> <head lang="en"> <m ...

  8. 【gearman】学习笔记

    学习资料:http://gearman.org/manual/ 1.Gearman是跨语言的,client和worker可以用不同的语言来实现 2.client与job server之间的交互称为ta ...

  9. linux ubuntu 指令

    查找文件:ls -lrt /java 用于查找java文件信息 https://ipcmen.com/ls编辑/etc/profilewen文件,在文件末尾添加export JAVA_HOME=/us ...

  10. laravel 中间件

    创建中间件命令 php artisan make:middleware CheckLogin 执行完以上命令会在app/Http/Middleware目录下创建一个新的中间件类CheckLogin.p ...