Django第十三篇----- Django 中的使用者許可權管理
目錄
概覽
Django 的身份驗證系統既能驗證身份,也能核准許可權。簡單來說,身份驗證是指確認使用者是不是他聲稱的那個人,而許可權核准是指確定通過身份驗證的使用者能做什麼。這裡,我們使用“身份驗證”指代這兩個任務。
Django 的身份驗證系統包括:
• 使用者
• 許可權:二元(是或否)旗標,指明使用者是否能執行特定的任務
• 分組:把標註和許可權賦予多個使用者的通用方式
• 可配置的密碼雜湊系統
• 管理身份驗證和許可權核準的表單
• 登入使用者或限制內容的檢視工具
• 可更換的後端系統
使用 Django 的身份驗證系統
Django 的身份驗證系統預設實現了多數常見的需求,能處理相當多的任務,而且小心實現了密碼和許可權。如
果你的專案不想使用預設的實現,Django 也允許對身份驗證系統做深入地擴充套件和定製。
User 物件
User 物件是這個身份驗證系統的核心,通常用於標識與網站互動的人,還用於限制訪問、記錄使用者資料,以及把內容與建立人關聯起來,等等。在 Django 的身份驗證框架中,只有一個使用者類存在,因此 superusers或管理後臺的 staff 使用者只是設定了特殊屬性的使用者物件,而不是分屬不同類的使用者物件。預設使用者主要有下面幾個屬性
• username
• password
• email
• first_name
• last_name
建立超級使用者
超級使用者使用 createsuperuser 命令建立:
python manage.py createsuperuser --username=joe [email protected]
建立使用者
建立和管理使用者最簡單、最不易出錯的方式是使用 Django 管理後臺。Django 還內建了登入、退出和修改密碼的檢視和表單。本章後面會說明如何通過管理後臺和普通的表單管理使用者,現在先來看如何直接驗證使用者的身份。
建立使用者最直接的方式是使用 create_user() 輔助函式:
>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user('*', '*@*.com', '*')
# 此時,user 是一個 User 物件,而且已經儲存到資料庫中
# 如果想修改其他欄位的值,可以繼續修改屬性
>>> user.last_name = 'Lennon'
>>> user.save()
修改密碼
Django 不在使用者模型中儲存原始(明文)密碼,只儲存密碼的雜湊值。因此,不要試圖直接處理使用者的密碼。正是因為這樣,建立密碼才要使用一個輔助函式。如果想修改使用者的密碼,有兩個選擇:
1. 在命令列中使用 manage.py changepassword username 命令修改使用者的密碼。這個命令會提示你輸入兩次密碼。如果兩次輸入的內容匹配,立即修改密碼。如果不指定使用者名稱,這個命令會嘗試修改與當前系統使用者的使用者名稱一致的那個使用者的密碼。
2. 還可以通過程式設計方式,使用 set_password() 方法修改:
>>> from django.contrib.auth.models import User
>>> u = User.objects.get(username='*')
>>> u.set_password('**')
>>> u.save()
許可權和許可權核准
Django 自帶了一個簡單的許可權系統。通過它可以為指定的使用者和使用者組賦予許可權。Django 管理後臺就用到了這個系統,當然也歡迎在你自己的程式碼中使用。Django 管理後臺使用許可權控制下述操作:
• 限制有某種物件的“新增”許可權才能檢視“新增”表單和新增物件。
• 限制有某種物件的“修改”許可權才能檢視修改列表、“修改”表單和修改物件。
• 限制有某種物件的“刪除”許可權才能刪除物件。
預設許可權
在 INSTALLED_APPS 設定中列出 django.contrib.auth 後,安裝的各個應用中的每個 Django 模型預設都有三個許可權:新增、修改和刪除。每次執行 manage.py migrate 命令建立新模型時都會為其賦予這三個許可權。
分組
django.contrib.auth.models.Group 模型是為使用者分類的通用方式,這樣便可以為一批使用者賦予許可權或新增其他標註。使用者所屬的分組數量不限。一個分組中的使用者自動獲得賦予那個分組的許可權。例如“Site editors”分組有 can_edit_home_page 許可權,那麼其中的任何一個使用者都有這個許可權
除了許可權之外,分組還是為使用者分類的便捷方式,分組後可以給使用者新增標籤,或者擴充套件功能。例如,可以建立“Special users”分組,然後編寫程式碼,允許這一組中的使用者訪問只有會員才能檢視的內容,或者傳送只給會員看的電子郵件。
Web 請求中驗證身份
Django 使用會話和中介軟體把身份驗證系統插入 request 物件,為每個請求提供 request.user 屬性,表示當前使用者。如果未登陸,這個屬性的值是一個 AnonymousUser 例項,否則是是一個 User 例項。這兩種情況可以使用 is_authenticated() 方法區分,例如:
if request.user.is_authenticated():
# 處理通過身份驗證的使用者
else:
# 處理匿名使用者
Django 如何儲存密碼
Django 提供了一個靈活的密碼儲存系統,預設使用 PBKDF2 演算法。 User 物件的 password 屬性是這種格式的字串:
<algorithm>$<iterations>$<salt>$<hash>
這是儲存使用者密碼的各個部分,之間以美元符號分隔。各部分分別是:雜湊演算法、演算法的迭代次數(工作係數)、隨機鹽值和最終得到的密碼雜湊值
algorithm 是 Django 支援的某種單向雜湊(或稱“密碼儲存”)演算法(參見下文)。 iterations 是在雜湊值上運用演算法的次數。 salt 是使用的隨機種子,而 hash 是單向演算法得到的結果。Django 預設使用 PBKDF2 演算法,得到 SHA256 雜湊值。這是 NIST 推薦使用的密碼增強機制,對多數使用者來說足夠了。這種演算法相當安全,需要用大量時間計算才能破解。然而,根據具體的需求,你可能想選擇其他的演算法,甚至自己動手實現一種演算法,滿足特殊的安全條件。再次說明,多數使用者無需這麼做。如果你不確定自己該不該這麼做,那有可能就不需要。
如果確實需要這麼做,請接著讀:Django 根據 PASSWORD_HASHERS 設定選擇演算法。這個設定的值是一個類列表,列出你所安裝的 Django 支援的雜湊演算法。其中第一個元素(即 settings.PASSWORD_HASHERS[0] )用於儲存密碼,其餘的都可用於檢查現有密碼。