本章著重總結(jié)Django的用戶與認證
一. cookies
? ? http(s)本身是無狀態(tài)的魏身,當前請求和下次請求之前無任何狀態(tài)保持惊橱,為了存儲狀態(tài),首先應(yīng)運而生的是cookies箭昵。在Django中税朴,每個request都包含了一個COOKIES對象,可以像字典一樣使用它。
? ? 雖然cookies能解決了狀態(tài)保持問題家制,但是引出了其他問題:
? ? ? ? a. 瀏覽器不保證會存儲,是否接受cookies在瀏覽器端用戶可以控制正林;
? ? ? ? b. cookies在瀏覽器中是可清除的,不可存儲重要信息颤殴,否則可能發(fā)生不可恢復(fù)的問題觅廓;
? ? ? ? c. http是明文傳輸,因此中間人容易攔截獲取cookies并使用涵但,不安全杈绸,容易被篡改;
?
二. session
? ? 為了解決cookies所帶來的問題矮瘟,session(會話)已然成為了web開發(fā)青睞的手段瞳脓。在Django中,自帶session框架解決了這個需求,存取每個用戶的任意數(shù)據(jù)芥永,該數(shù)據(jù)可存儲在服務(wù)器端或者以文件等方式存儲篡殷。
?
? ? 在Django中钝吮,sessions 功能是通過一個中間件(middleware)和一個模型(model)來實現(xiàn)的埋涧,為了使用session功能,需要確認以下(默認情況是打開):
? ?? ? a. 確認MIDDLEWARE(中間件) django.contrib.sessions.middleware.SessionMiddleware
被添加在MIDDLEWARE
? ?? ? b. 確認 session app(系統(tǒng)) django.contrib.sessions
被添加在INSTALLED_APPS
? ?激活后奇瘦,每個httpRequest都有一個session屬性棘催,是一個字典對象,每個session對象都是由一個隨機的32位哈希串來標識
?
? ? 由于session是依賴cookies來設(shè)計的耳标,session的有效期等需要進行一些設(shè)置醇坝,比如關(guān)閉瀏覽器失效還是有效期一個星期失效等,常用的如下:
? ? ? ? 1. SESSION_ENGINE
設(shè)置引擎次坡,決定session保存在哪里呼猪,默認數(shù)據(jù)庫
? ? ? ? 2. SESSION_COOKIE_NAME
Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串
? ? ? ? 3. SESSION_COOKIE_PATH
保存的路徑
? ? ? ? 4. SESSION_COOKIE_DOMAIN
保存的域名
? ? ? ? 5. SESSION_COOKIE_SECURE
是否https傳輸cookie
? ? ? ? 6. SESSION_COOKIE_AGE
cookie的有效期
? ? ? ? 7. SESSION_EXPIRE_AT_BROWSER_CLOSE
是否關(guān)閉瀏覽器就失效
? ? ? ? 8. SESSION_SAVE_EVERY_REQUEST
是否每次請求都保存Session砸琅,默認修改之后才保存
?
三. 用戶宋距、認證與授權(quán)
? ? auth模塊(app)是Django提供的標準認證與授權(quán)系統(tǒng),主要做2件事:
? ?? ? a. 認證用戶症脂,主要比對系統(tǒng)中是否存在該用戶
? ?? ? b. 檢查權(quán)限谚赎,主要確定用戶是否有某些操作淫僻,即被授權(quán)某些操作
? ? 默認情況,應(yīng)用到的中間件django.contrib.auth.middleware.AuthenticationMiddleware
和app 系統(tǒng)django.contrib.auth
是打開的壶唤。User模型是auth模塊中維護的用戶信息關(guān)系模型雳灵。主要字段用戶名蔗喂、密碼膀息、郵箱等辅斟,可在auth/models.py
中查看具體姐军,繼承關(guān)系如下
? ?? ?User----繼承----> AbstractUser---->AbstractBaseUser和PermissionsMixin
? ? 其中AbstractBaseUser定義了對象字段和操作數(shù)據(jù)表的API儒将,PermissionsMixin定義了權(quán)限相關(guān)內(nèi)容
? ? 本次建系統(tǒng)的過程中员舵,用戶內(nèi)置的User不夠滿足需求工扎,采用了擴展AbstractUser的方式泪酱,怎么創(chuàng)建適合的User模型得看需求钓觉,這篇文章已經(jīng)說得很清楚茴肥,可參考:http://www.cnblogs.com/yxi-liu/p/8684504.html
?
? ? 用戶的認證
? ?? ?authenticate(),通過用戶名稱和密碼進行用戶的認證
? ?? ?login(request, user),該函數(shù)接受一個 HttpRequest 對象和一個 User 對象作為參數(shù)并使用Django的會話( session )框架把用戶的ID保存在該會話中
? ?? ?logout(),實際就是清除了session中的user信息荡灾,它接受一個HttpRequest對象并且沒有返回值,所以瓤狐,因為沒有返回值,需要返回一個頁面批幌。
from django.contrib.auth import login,logout,authenticate
user=authenticate(username=userName, password=password)
if user is not None and user.is_active:
login(request, user)#認證通過后础锐,調(diào)用login方法,主要是設(shè)置session
?
?
? ? 說完了用戶的問題荧缘,接下來說說權(quán)限與組
? ? 使用auth 原生或擴展的User皆警,執(zhí)行完migrate
和makemigrations
,即python3 manage.py migrate auth``python3 manage.py makemigrations auth
后截粗,會在數(shù)據(jù)庫中生成3個表
? ? ? ? auth_group:組信姓,包括id和name
? ? ? ? auth_group_permission: 組權(quán)限,包括id绸罗、group_id意推、permission_id
? ? ? ? auth_permission: 權(quán)限信息,包括name珊蟀、content_type_id和codename字段菊值,codename主要是使用權(quán)限方法傳入的參數(shù),content_type_id與模型相關(guān)
? ? permission總是與model對應(yīng)的育灸,如果一個object不是model的實例腻窒,我們無法為它創(chuàng)建
?
? ? 在創(chuàng)建model時,可通過元類的方式自定義權(quán)限
class Meta:
permissions =
(
("view_server", "can view server"),//(codename,name)
("change_server_status", "Can change the status of server"),
)
? ? 或者通過腳本的方式設(shè)置權(quán)限
#假設(shè)model為blog磅崭,app為blogs
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import Permission
content_type=ContentType.objects.get_for_model(blog)
permissions=Permission.objects.create(codename="can_edit_blog",name="edit blog ",content_type=content_type)
#以上權(quán)限可通過user_permissions或permission屬性的Groups分配給一個User對象
user.user_permissions.add(permissions)
group=Group.objects.get(name='only_view_person')
user.groups.add(group)
#以上只是舉例為用戶添加權(quán)限儿子,其他方法有clear()、set()绽诚、remove()
? ? 驗證權(quán)限
user.has_perm('blogs.can_edit_blog')#或者使用裝飾器@permission_required("blogs.can_edit_blog")裝飾函數(shù)
#頁面驗證權(quán)限
{%if perms.blogs.can_edit_blog%}