django(权限、认证)系统——用户Login,Logout
上面两篇文章,讲述的Django的Authentication系统的核心模型对象User API和相关的使用,本文继续深入,讨论如何在Web中使用Authentication系统。
前面说了,Django的这套权限系统有三个核心,User,Permission,Group。
而在Web应用中,任何的权限系统要做的第一步就是用户识别,也就是我们常说的登陆(login)。只有正确的登陆校验,知道用户是谁了,才能够知道用户能干什么,那就是许可(Permission)需要负责解决的事情,而Group则是批量设置许可的时候的一个便利手段了。
Web请求的认证:
django有一套方法,可以在每个view方法能够接收到的request对象中增加权限验证相关的方法。要做到这一点,首先需要:
- 安装SessionMiddleware和AuthenticationMiddleware。安装方法在settings文件中对MIDDLEWARE_CLASSES变量增加上述两个Middleware类。Middleware的设计几乎在任何web框架中都有体现,只不过叫法和具体实现的手段不尽相同,例如在struts2中叫做interceptor拦截器,采用函数递归Stack的方式实现(其它框架没见过有这么干的)。设计思路都是在request进入最后的处理方法之前经过一个个前处理,在处理方法处理完之后再经过一个个后处理,前后的次序恰好相反。有点点走题,请看例子:

1 MIDDLEWARE_CLASSES = (
2 'django.contrib.sessions.middleware.SessionMiddleware',
3 'django.middleware.locale.LocaleMiddleware',
4 'django.middleware.common.CommonMiddleware',
5 'django.middleware.csrf.CsrfViewMiddleware',
6 'django.contrib.auth.middleware.AuthenticationMiddleware',
7 'django.contrib.messages.middleware.MessageMiddleware',
8 'django.middleware.transaction.TransactionMiddleware',
9 )
一旦安装好了之后,在view中,我们就可以使用request.user获取当前的登陆用户User对象。如果当前用户没有登陆,那么request.user将会是我们之前所说的AnonymousUser对象。我们可以用User对象的is_authenticated()方法将这两者区分开来:
if request.user.is_authenticated(): # 做一些事情针对验证用户.else: # 做一些事情对于匿名未登录用户.
那么如何登陆一个用户呢?
需要两个函数:authenticate(username,password)和login(request,user),位于django.contrib.auth模块中;
这两个方法需要结合使用,
1.authenticate(username,password)函数需要两个参数username,password,如果校验通过则返回User对象,如果校验不通过返回None,例如:
from django.contrib.auth import authenticateuser = authenticate(username='john', password='secret')if user is not None: if user.is_active: print "You provided a correct username and password!" else: print "Your account has been disabled!"else: print "Your username and password were incorrect."2.login接受两个参数,第一个是request对象,第二个是user对象。login方法使用SessionMiddleware将userID存入session当中。注意,在用户还未登录的时候,也存在着匿名用户的Session,在其登陆之后,之前在匿名Session中保留的信息,都会保留下来。这两个方法要结合使用,而且必须要先调用authenticate(),因为该方法会User的一个属性上纪录该用户已经通过校验了,这个属性会被随后的login过程所使用,例如:
from django.contrib.auth import authenticate, logindef my_view(request): username = request.POST['username'] password = request.POST['password'] user = authenticate(username=username, password=password) if user is not None: if user.is_active: login(request, user) # 跳转到成功页面. else: # 返回一个无效帐户的错误 else: # 返回登录失败页面。我们也可以不用authenticate()进行特定于一个用户的身份校验,直接使用和User无关的几个函数进行密码相关的校验,在Django1.4中以及新版本中提供以下方法,位于模块django.contrib.auth.hashers:
- check_password(password,encoded):第一个参数是明文密码,第二个参数是加密过的密码。如果通过校验返回True,不通过返回False;
- make_password(password[,salt,hashers]):根据给定的明文密码,salt,和Django支持的加密算法,返回一个加密的密码。如果password提供的值为None,那么该返回值将永远通不过check_password()方法。这个返回值是一个特定的约定值,目前是'!';
- is_password_usable(encoded_password):判断是否给定字符串是一个hashed密码,有机会通过check_password()函数的校验。
接下来,如何登出(log out)一个用户?
我们使用django.contrib.auth.logout函数来登出用django.contrib.auth.login函数登入的用户。
logout(requet)
函数只有一个参数,就是request。没有返回值,而且即使当前用户没有登陆也不会抛出任何异常。
例子:
from django.contrib.auth import logoutdef logout_view(request): logout(request) # 重定向到成功登出界面这个方法,会将存储在用户session的数据全部清空,这样避免有人用当前用户的浏览器登陆然后就可以查看当前用户的数据了,回想一下login会保留anonymous用户的session数据。如果需要将一些东西加入到登出之后的用户session,那么需要在logout方法调用之后再进行。
接下来介绍Login和Logout的两个signals
Django的signal体系是一套简单实用的事件定义、事件产生、事件监听、事件处理框架,具体可以参看Django关于signal的文档。在登陆和登出这两个重要的点上,提供了两个signal:
- django.contrib.auth.signals.user_logged_in
- django.contrib.auth.signals.user_logged_out
有三个参数会随singal传过来:
- sender:user的class,如果是logout事件该值有可能是None如果用户根本就没有验证通过。
- request:HttpRequest对象
- user:user对象,如果是logout事件该值有可能是None如果用户根本就没有验证通过。
一个经常性的简单需求就是控制某些view(struts中叫做action方法)只对登陆用户开放,如果未登录用户请求该view则跳转到登录界面让其登陆。要做到这一点,我们可以这样做:
from django.http import HttpResponseRedirectdef my_view(request): if not request.user.is_authenticated(): return HttpResponseRedirect('/login/?next=%s' % request.path) # ...也可以这样做,返回一个错误的页面:
def my_view(request): if not request.user.is_authenticated(): return render_to_response('myapp/login_error.html') # ...更为优雅的方式是用decorator:
django.contrib.auth.decorators.login_required([redirect_field_name=REDIRECT_FIELD_NAME,login_url=None])
login_required()装饰器函数做了以下事情:
- 如果当前用户没有登陆,跳转到settings.LOGIN_URL,并传递当前的绝对路径到URL请求参数中,例如:/accounts/login/?next=/polls/3/
- 如果当前用户已经登陆了,执行view方法。在view中的方法可以认为当前用户已经登陆了。
login_required方法接受两个参数:
- redirect_field_name:默认值是next。用来定义登陆成功之后的跳回之前访问界面的url。
- login_url:默认值是settings.LOGIN_URL。用来指定登陆界面的url。如果不传入改参数,就需要确保settings.LOGIN_URL的值是正确设置的。
没有参数的login_required装饰器使用方法:
from django.contrib.auth.decorators import login_required@login_requireddef my_view(request): ...传递参数的方法:
from django.contrib.auth.decorators import login_required@login_required(redirect_field_name='my_redirect_field')def my_view(request): ...from django.contrib.auth.decorators import login_required@login_required(login_url='/accounts/login/')def my_view(request): ...以上就是Django提供的用于完成login和logout相关的一些API支持,使用他们可以很好的对用户进行认证了,也就是说用户是谁系统已经搞清楚了,接下来就是更细粒度的判断,判断此人究竟能做些什么,也就是Permission许可的使用了。请看 Django中的权限控制-authentication-内置版本-4。
django(权限、认证)系统——用户Login,Logout的更多相关文章
- Django之认证系统
Django之认证系统 cookie和session 1.cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞 ...
- Django的认证系统—auth模块
Django的认证系统 auth模块的知识点总结: 1. 创建超级用户 python manage.py createsuperuser from django.contrib import auth ...
- Django的认证系统
Django自带的用户认证 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Djang ...
- Django auth认证系统
Django自带的用户认证 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Djang ...
- Django的认证系统 auth模块
Django自带的用户认证 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Djang ...
- 【Django】认证系统
目录 #. auth模块 1. 认证 authenticate() 2. 登陆 login(HttpRequest, user) 3. 注销 logout(request) 4. 认证判断 is_au ...
- Django 【认证系统】auth
本篇内容 介绍Django框架提供的auth 认证系统 方法: 方法名 备注 create_user 创建用户 authenticate 登录验证 login 记录登录状态 logout 退出用户登录 ...
- python框架之Django(12)-认证系统之auth模块
我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Django作为一个完美主义者的终极框 ...
- Django 的认证系统
Django自带的用户认证 auth 模块 from django.contrib import autu django.contrib.auth 中提供了许多方法, 这里主要介绍其中三个: auth ...
随机推荐
- bash配置文件说明
login shell: /etc/profile 所有用户全局设定,它首先会调用以下文件: /etc/inputrc /etc/profile.d/*.sh /etc/sys ...
- rails项目编写中的一些小技巧小心得
1. 如果form中有数据要传回服务器可以用隐藏属性的控件: form_for(xxx) do |f| f.hidden_field :xxx,value:xxx end 2. 如果你需要一些信息放在 ...
- jdk1.7 tomcat-7安装
由于软件下载地址经常有变动,所以不能直接wget,还是直接到网上点击下载 下载jdk http://www.oracle.com/technetwork/java/javase/downloads/j ...
- 致IT之路的先驱者和旅人
1,图灵和香农 故事的开始,要从计算机之父图灵和信息论的创始人香农开始说起.图灵最大的贡献是发明了图灵机,关于图灵机如果要让人明白究竟有什么用,从如何实现一个半导体电路图灵机这方面理解比较好.只要一个 ...
- eclipse乱码
eclipse乱码:Windows >general >Workspace UTF-8Windows >general >Editors >Text Editors &g ...
- LR性能测试结果样例分析
http://www.cnblogs.com/hyzhou/archive/2011/11/16/2251316.html 测试结果分析 LoadRunner性能测试结果分析是个复杂的过程,通常可 ...
- virtualenv 中 install flask 的小问题
最经在学习Python flask 框架 ,用virtualenv建立好我的flask虚拟环境后,执行 sudo pip install flask 并没有报错 我以为已经装上了flask,但当我进入 ...
- sql数据行转列
select CodeName FROM CodeDictionary where CodeCategory_ID=138结果: ) GROUP BY CodeName SET @sql='selec ...
- mysql-列属性
列属性 列属性是真正约束字段的数据类型,但是数据类型的约束很单一,需要有一些额外的约束来确保数据的合法性 NULL/NOT NULL.default.primary key.unique key.au ...
- 落入绝地求生的Python神仙,实现绝地求生无后座!
叙述 绝地求生已经出来那么久了,大家应该都晓得如今的游戏情形很是差 .特别在高端局,神仙满天飞 搞得很多人类玩家很是没有游戏体验! 由于绝地求生的火爆,繁衍出许多外挂流传于各个地方.飞机上.网吧内,各 ...