[django]總結Django中的用戶權限模塊

原文:http://maplye.iteye.com/blog/448960html

該模塊由
用戶(Users)
權限(Permissions)
組(Groups)
消息(Messages)數據庫

一、安裝
1)將'django.contrib.auth'添加到Setting.py的INSTALLED_APPS 中
2)安裝數據庫 manage.py syncdb.
其實用戶權限模塊是Django本身已經寫好的app,因此他也具備自身的Models,因此須要同步數據庫。django

二、User
1)屬性
其中他包含User類,他具備如下字段
username,first_name,last_name,email,password,is_staff(是否具備進入網站管理權限),
is_active,is_superuser,last_login,date_joined.app

這是Django自帶的User的基本的信息,若是你要使用該權限模塊,就必需要使用他的User類,
可是一般狀況下,咱們的用戶信息還會有其餘的屬性,這時咱們能夠再增長一類來擴展,該類和User的關係是OneToOne。
如:
#這是china-django中的代碼post

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')ui

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):給某用戶發送郵件this

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錯誤url

三、User的驗證
1)登錄(Login)code

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/')

四、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 %}

五、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

這個時候咱們須要修改SettingAUTHENTICATION_BACKENDS = ( 'sputnik.backends.ldapBackend.LDAPBackend',)

相關文章
相關標籤/搜索