此文是总结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!!!
参考资料:
[django]总结Django中的用户权限模块:http://maplye.iteye.com/blog/448960
[ios]将 django.contrib.auth.views.login 设置为 csrf_exempt:http://www.itstrike.cn/Question/85f57468-58d3-4a40-89d3-c865b63b0c02.html