[django]总结Django中的用户权限模块

本文深入探讨了Django框架中用户认证、权限、组及消息模块的应用与实现,详细介绍了用户类属性、方法,匿名用户与认证用户的区别,用户验证流程,包括登录、注销、非法用户访问限制等,同时提供了模板中用户验证的实现方式以及自定义权限的定义与使用。

出处:http://blog.youkuaiyun.com/zeng_84_long/article/details/8153993

此文是总结Django官方网站里面的Document的文章 User authentication in Django
http://www.djangoproject.com/documentation/authentication/


http://www.cnblogs.com/lddhbu/archive/2012/06/26/2564072.html


该模块由
用户(Users)
权限(Permissions)
组(Groups)
消息(Messages)

这些从字面上也都很好的理解,但是我对消息(Messages)还不是很理解…………


1、安装
1)将'django.contrib.auth'添加到Setting.py的INSTALLED_APPS 中
2)安装数据库 manage.py syncdb.
其实用户权限模块是Django自己已经写好的app,所以他也具有自身的Models,所以需要同步数据库。

2、User
1)属性
其中他包含User类,他具有以下字段
username,first_name,last_name,email,password,is_staff(是否具有进入网站管理权限),
is_active,is_superuser,last_login,date_joined.

这是Django自带的User的基本的信息,如果你要使用该权限模块,就必须要使用他的User类,
但是通常情况下,我们的用户信息还会有其他的属性,这时我们可以再增加一类来扩展,该类和User的关系是OneToOne。
如:
#这是china-django中的代码

class  Profile(models.Model):
    user 
=  models.OneToOneField(User)

    blog 
=  models.CharField(maxlength = 128 , blank = True)
    location 
=  models.CharField(maxlength = 128 , blank = True)
    occupation 
=  models.CharField(maxlength = 64 , blank = True)
    
    reward 
=  models.IntegerField(default = 0, blank = True)
    topic_count 
=  models.IntegerField(default = 0, blank = True)
    post_count 
=  models.IntegerField(default = 0, blank = True)
    
    
class  Admin:
        list_display 
=  ( ' user ' ' blog ' ' location ' ' occupation ' ' reward ' ' topic_count ' ' post_count ' )

2)方法
这里列举几个主要的方法
is_anonymous():是否为匿名用户,如果你已经login,则这个方法返回始终为false.
is_authenticated():是否通过验证,也就是通过用户名和密码判断该用户是否存在.
get_group_permissions():得到所有该用户所属组别的权限.
get_all_permissions():得到该用户所有的权限.
has_perm(perm):判断用户是否具有特定权限,perm的格式是appname.codename.
email_user(subject, message, from_email=None):给某用户发送邮件


3) AnonymousUser
AnonymousUser是继承自User接口,但是和User有不同处:
id属性为None
is_anonymous() 返回始终为True
is_authenticated() 返回始终为False
has_perm() 返回始终为False
set_password(), check_password(), save(), delete(), set_groups()和set_permissions() 都会触发 NotImplementedError错误


3、User的验证
1)登陆(Login)

from  django.contrib.auth  import  authenticate, login

def  my_view(request):
    username 
=  request.POST[ ' username ' ]
    password 
=  request.POST[ ' password ' ]
    user 
=  authenticate(username = username, password = password)
    
if  user  is   not  None:
        login(request, user)
        
#  Redirect to a success page.
     else :
        
#  Return an error message.

首先我们要验证这个用户,然后再登陆,登陆成功后,我们可以通过request.user 来得到当前登陆的用户对象。

2)注销(Logout)

from  django.contrib.auth  import  logout

def  logout_view(request):
    logout(request)
    
#  Redirect to a success page.

3)限制非法用户访问
最普通的方法是通过request.user.is_authenticated()来判断

from  django.http  import  HttpResponseRedirect

def  my_view(request):
    
if   not  request.user.is_authenticated():
        
return  HttpResponseRedirect( ' /login/?next=%s '   %  request.path)
    
#  

另外有一快捷的方法login_required

from  django.contrib.auth.decorators  import  login_required

@login_required
def  my_view(request):
    
#  

这样当你访问my_view的时候,就需要用户需要通过验证.若不通过则跳转到
/accounts/login/?next=/polls/3/
并将当前访问的页面作为他的一个参数,并且传递三个Context变量
form 一个FormWrapper 对象用来重构登陆表单
next 就是你访问的当前页面
site_name 当前站点名称,在Setting.py中设置SITE_ID的值

另外,我们还需要在你的urls里面配置/accounts/login路径
下面有两种两种,不同的是使用不同的模版,第一种默认使用registration/login.html 模版,第二种方式是我们自定义模版

(r ' ^accounts/login/$ ' ' django.contrib.auth.views.login ' ),
(r
' ^accounts/login/$ ' ' django.contrib.auth.views.login ' , { ' template_name ' ' myapp/login.html ' }),

一个login.html模版的实例:

{% extends "base.html" %}

{% block content %}

{% if form.has_errors %}
< p > Your username and password didn't match. Please try again. </ p >
{% endif %}

< form  method ="post"  action ="." >
< table >
< tr >< td >< label  for ="id_username" > Username: </ label ></ td >< td > {{ form.username }} </ td ></ tr >
< tr >< td >< label  for ="id_password" > Password: </ label ></ td >< td > {{ form.password }} </ td ></ tr >
</ table >

< input  type ="submit"  value ="login"   />
< input  type ="hidden"  name ="next"  value ="{{ next }}"   />
</ form >

{% endblock %}

4)用户是否有权限访问

当我们创建了一个带有class Admin:内类的类后,会自动add, create 和 delete三种权限,不过我们也可以自己定义权限。
如下:

class  USCitizen(models.Model):
    
#  
     class  Meta:
        permissions 
=  (
            (
" can_drive " " Can drive " ),
            (
" can_vote " " Can vote in elections " ),
            (
" can_drink " " Can drink alcohol " ),
        )

这样我们为USCitizen类定义了三种自定义的权限,其中第一项是codename,第二项是discription。  

当我们定义好权限后,我们可以通过user.has_perm来判断是否具有权限

def  my_view(request):
    
if   not  (request.user.is_authenticated()  and  request.user.has_perm( ' polls.can_vote ' )):
        
return  HttpResponse( " You can't vote in this poll. " )

has_perm的参数应该是appname(packname) + . + codename

还有一种更简便的方式,如下:
@user_passes_test(lambda u: u.has_perm('polls.can_vote'))
这样如果该用户没有权限,则自动跳转到/accounts/login/,也可以自定义跳转
@user_passes_test(lambda u: u.has_perm('polls.can_vote'), login_url='/login/')

4、template中的用户验证
Users

{% if user.is_authenticated %}
    
< p > Welcome, {{ user.username }}. Thanks for logging in. </ p >     
{% else %}
    
< p > Welcome, new user. Please log in. </ p >
{% endif %}

Permissions
{{ perms.foo }},一个已经登陆的用户对foo的app只要有任何的权限,{{ perms.foo }}就会等于True,反之为False
{{ perms.foo.can_vote }}, 这个很清楚了...
实例如下:

 

{% if perms.foo %}
    
< p > You have permission to do something in the foo app. </ p >
    {% if perms.foo.can_vote %}
        
< p > You can vote! </ p >
    {% endif %}
    {% if perms.foo.can_drive %}
        
< p > You can drive! </ p >
    {% endif %}
{% else %}
    
< p > You don't have permission to do anything in the foo app. </ p >
{% endif %}

5、authentication backends
Django中队用户的验证都是通过自身的模块,也可以使用其他的模块。
默认的AUTHENTICATION_BACKENDS 是
('django.contrib.auth.backends.ModelBackend',)

我们可以自己写一个不同的用户验证方式,但必须具有get_user 和authenticate方法
如:

from  django.conf  import  settings
from  django.contrib.auth.models  import  User, check_password

class  SettingsBackend:
    
"""
    Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD.

    Use the login name, and a hash of the password. For example:

    ADMIN_LOGIN = 'admin'
    ADMIN_PASSWORD = 'sha1$4e987$afbcf42e21bd417fb71db8c66b321e9fc33051de'
     """
    
def  authenticate(self, username = None, password = None):
        login_valid 
=  (settings.ADMIN_LOGIN  ==  username)
        pwd_valid 
=  check_password(password, settings.ADMIN_PASSWORD)
        
if  login_valid  and  pwd_valid:
            
try :
                user 
=  User.objects.get(username = username)
            
except  User.DoesNotExist:
                
#  Create a new user. Note that we can set password
                 #  to anything, because it won't be checked; the password
                 #  from settings.py will.
                user  =  User(username = username, password = ' get from settings.py ' )
                user.is_staff 
=  True
                user.is_superuser 
=  True
                user.save()
            
return  user
        
return  None

    
def  get_user(self, user_id):
        
try :
            
return  User.objects.get(pk = user_id)
        
except  User.DoesNotExist:
            
return  None

这个时候我们需要修改Setting
AUTHENTICATION_BACKENDS = (
 'sputnik.backends.ldapBackend.LDAPBackend',
)

这里还有一片关于Authentication Backends的文章

LDAP Authentication in Django with Backends

全文结束,谈不上总结,因为缺少我的体会和心得,也谈不上翻译,因为my englishi is Poor.

See You!!!

 

注意事项:

1.无论你是否使用了csrf,django自带的用户验证都需要使用到csrf。所以,在form的后面请加上{% csrf_token %}:

<form method="post">{% csrf_token %}


 

2.如果使用了ldap进行用户验证,我们还需要在settings.py文件中对ldap进行配置:

AUTH_LDAP_SERVER_URI = "ldap://xxxxx"
AUTH_LDAP_BIND_DN = 'cn=x,cn=x,dc=x,dc=x'
AUTH_LDAP_BIND_PASSWORD = 'xxxxx'
AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=x,dc=x,dc=x", ldap.SCOPE_SUBTREE, "(xxx)")


 

ok!

转载于:https://www.cnblogs.com/chenjianhong/archive/2013/03/06/4144824.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值