django-用戶驗證系統


django提供了一套用戶驗證系統,但是要使用這個系統,必須要使用django內置的用戶模型:django.contrib.auth.models.User,這個模型中預先定義了一些字段,其中只有username和password是必須的。
 
username
用戶名,該字段是必須的,長度限制版本之間可能存在差異,1.10為150個字符以內(其他版本為30個字符,存在版本差異)。可以是字母、數字、+、-、_、.、@。這幾個字符。在1.10版本中,django正式支持utf-8的用戶名(也就是不受字符限制了),當然前提是要使用python3.x的版本。
 
當然,你也可以使用max_length、min_length等屬性來控制用戶名的長短限制。下面的字段基本也適用。
 
django在1.10中實現了兩個驗證器,其會根據python版本自動選取,一般不用我們擔心。可以使用username_validator(New in Django 1.10.)屬性查看驗證器:默認  validators.UnicodeUsernameValidator於Python 3 、 validators.ASCIIUsernameValidator於Python 2.
 
當然我們也可以改變驗證器,例如將python3的驗證器改成ASCII的:
 
from django.contrib.auth.models import User
from django.contrib.auth.validators import ASCIIUsernameValidator
class CustomUser(User):
  username_validator = ASCIIUsernameValidator()
  class Meta:
    proxy = True # If no new field is added.

 

上面我們首先子類化了User model,然后改變了username_validator屬性,這也是標准的修改步驟。
 
password
密碼,必須。django不會直接儲存原始密碼,而是儲存經過處理之后的哈希值。所以在創建用戶或修改密碼的時候不能直接操作這個屬性,而是使用django提供的專門的方法,下面會再說明。
 
email
可選,表示email地址。
 
first_name
可選,30個字符以內(在中文環境中應該用不上)
 
last_name
可選,30個字符以內
 
groups
Many-to-many relationship to  Group
Group屬於多對多的關系,而 Group表示的是用戶組,由另一種表儲存。
 
user_permissions
Many-to-many relationship to  Permission
Permission屬於多對多的關系,而 Permission表示的是權限,由另一種表儲存。
關於權限的問題需要另外說明,這里暫時不討論。
 
is_active
表用戶是否是活躍的,是一個布爾值。django提議與其刪除一個用戶的所有信息,還不如將其設置為非活躍(即凍結)狀態。這樣不會破壞其他相關的外鍵關系,同時也擁有了后悔的可能。
 
注意:在1.10之前,django的后台驗證程序不會檢查用戶是否處於活躍狀態,也就是非活躍的用戶依然可以登錄,此時要自己進行狀態驗證,例如:
 
if user.is_active: # 若用戶是活躍的,即未凍結的,在1.10之前凍結用戶默認也能登錄,所以需要自己認證
    login(request, user) # 登錄
    ...... #其他處理
else:
    return HttpResponse('用戶被凍結')

 

在1.10版本中,django的默認驗證后台會拒絕凍結用戶的訪問了。當凍結的用戶登錄時,會無法通過  authenticate(username=None, password=None, **kwargs) 的驗證,即該方法會返回None。
 
is_staff
是否為staff身份,布爾值。擁有staff身份的用戶可以登錄django的admin后台,且可以使用  staff_member_required(redirect_field_name='next', login_url='admin:login') 裝飾器來進行訪問控制。詳情參考 django-訪問控制 篇。
 
is_superuser
是否是superuser身份,布爾值。擁有該身份的用戶將能夠登錄admin后台,並擁有所有注冊模型的管理權限。
 
last_login
用戶最后登錄的時間。
 
date_joined
用戶創建的時間。
 
以上就是django自帶的用戶認證系統使用的模型的全部字段了,也就是說django在數據庫中儲存的字段信息就是以上這些,如果需要擴展的話,有兩種方法:
 
1.另外再寫一個模型,用OneToOne的形式關聯到User中:
 
 
from django.db import models
from django.contrib.auth.models import User
 
 
class UserInfo(models.Model):
    user = models.OneToOneField(User)
    head_img = models.ImageField()
    # 其它擴展

 

 
2.另寫一個模型,直接繼承User:
 
from django.db import models
from django.contrib.auth.models import User
 
 
class UserInfo(User):
    head_img = models.ImageField()
    # 其它擴展

 

 
無論哪種方法都可以,因為那些已經定義好的字段都是儲存在User表中的,而新增的字段儲存在另外的表中,只是使用OneToOne的時候,查詢的入口略麻煩了些,詳情參考django的models。
 

用戶注冊:
 
所謂的用戶注冊,其實就是在User表中新創建一條記錄,而前面說過了,password字段儲存的不是原始密碼,而是加密后的字符串,所以不能直接對User對象的屬性進行修改,而是要調用專用的函數:
 
>>> from django.contrib.auth.models import User >>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')

 

此時,用戶就已經創建 並放到數據庫中了,這個方法比較特別,其自動為我們保存數據。
 

密碼修改:
 
由於密碼字段不能直接操作,所以django也提供了函數專門用來修改密碼:
 
>>> from django.contrib.auth.models import User 
>>> u = User.objects.get(username='john')
>>> u.set_password('new password') 
>>> u.save()

 

這里有一個細節,它不像創建賬戶一樣會直接保存的數據庫中,而是調用User對象的save()方法,表示將修改保存到數據庫中。
 

資料修改:
 
其他的字段可以通過直接修改對象屬性的方法來修改數據,然后調用保存方法。
 
例如,我想修改用戶的email:
 
request.user.email = date['email'] # date的表單提交上來的數據
request.user.save() # 保存修改

 

 
一般資料修改需要用戶登錄之后才能修改,而登錄后的用戶可以是使用request.user來獲取當前登錄的用戶,然后我們直接對其email屬性進行修改,數據來自於用戶提交的表單(你可以直接將其看成'scolia@example.com'這樣的直接的字面量)。最后我們調用其save方法,其實除了password相關的操作需要調用輔助函數之外,其他的基本都能這樣修改,這也是模型數據修改的典型方法。
 

用戶驗證:
 
要實現我們平常需要的驗證登錄的功能,需要兩個步驟,第一步是驗證用戶名和密碼是否正確,第二步將用戶登錄。
 
from django.contrib.auth import authenticate
 
user = authenticate(username=date['user_name'], password=date['password'])

 

username和password兩個參數分別接受要登錄用戶的用戶名和密碼,這里傳的是明文。 若驗證通過,其會返回User對象,這個User對象記錄了所用的用戶信息,你可以對這個對象進行資料的修改等之類的操作。 若登錄失敗則返回None
 
用戶登錄:
 
驗證成功之后,就可以進行登錄操作了,django提供了專門的登錄函數來處理這個工作:
 
from django.contrib.auth import authenticate, login
 
user = authenticate(username=date['user_name'], password=date['password'])

if user is not None:
    login(request, user)
    #.....
else:
    return HttpResponse('用戶名或密碼錯誤')

 

這里的核心思想就是登錄失敗后,返回的是None,而判斷到user不為None,即驗證成功了,就可以
進行登錄操作了,否則返回錯誤。
 
這里詳細的了解一下login這個函數:
 
  login(request, user, backend=None) 
 
其中request要求的是HttpRequest對象,也就是視圖的第一個參數所接受到的對象,習慣性的使用request,user要求要登錄的User對象,也就是驗證成功后返回的User對象。backend是1.10中新增的,其作用是指定特點的后台程序,一般用不着,若有特殊需求可以參考django1.10的官方文檔。
 
由於HTTP協議是無狀態協議,所以使用的拓展的cookie和session首部來進行狀態記錄,django采用的是session,在登錄成功后,django會給客戶端設置session首部,其一般是一個用戶的ID,而不是用戶的詳細信息。客戶端登錄后訪問時都會回送這個ID,django接受到ID后找到對應的用戶,從而得知當前的訪問是哪個用戶。實現了登錄的功能。
 

用戶注銷:
 
上面說過用戶的狀態是通過session來記錄的,也就是將session設置為空后,即丟失登錄狀態,這就是注銷了。django同樣提供了變量的函數來完成這個工作:
 
 
from django.contrib.auth import logout
 
def logout_view(request):
    logout(request) # Redirect to a success page.

 

讓我們來認識一下這個函數:
 
  logout(request) 
 
其接收的只有一個參數,也就是當前的request對象。其所完成的就是重置session的工作。如果用戶沒有登錄,也不會報錯。
 
注意:這個還是會清空所有的session,也就是說如果你有不希望被刪除的session的話,要先獲取到相應的session,並在調用logout之后再將其收到添加進去。
 

 
這里初步解釋了django中用戶驗證系統的使用,要獲取更多信息可以查看官方文檔,或者個人提供了一份略微翻譯了的文檔: http://note.youdao.com/yws/public/redirect/share?id=b67cd6af80e4c59da71c47b85b5f3253&type=false


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM