此文是总结Django官方网站里面的Document的文章 User authentication in Django
http://www.djangoproject.com/documentation/authentication/
该模块由
用户(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!!!