在這篇文章中,我們進行最后關於DjangoPermission系統的探討,來談談關於Permission系統后台接口和擴展后台接口的開發。
Django實現的這套permission體系,在底層被抽象為authentication backends。Django auth backends的默認的內置的實現,就是我們前4篇blog所描述的,基於三個數據庫模型User,Permission,Group。在實際開發中,很有可能我們的用戶標示或者是密碼並非存在於User表中,比如說存放在LDAP中,再比如使用第三方的OAuth。這就需要我們能夠對已有的權限系統進行擴展,而不是局限於基於數據庫表的權限控制,這也是Django將其抽象為可以定制的authentication backends的緣由。
Django中,所有的authentication backends,可以通過配置settings中的一個變量AUTHENTICATION_BACKENDS來做到,這個變量的類型是元組(Tuple),默認Django的設置是:
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)
Backend可以是普通的python類,但是關於登陸校驗需要具有以下規定的2個方法:
- authenticate(self,username=None,password=None) 或者authenticate(self,token=None),如果通過驗證,返回值是一個User對象,如果不通過驗證,返回值是None。
- get_user(self,user_id)
關於許可,需要有以下幾個方法:
- get_group_permissions
- get_all_permissions
- has_perm
- has_module_perms
這兩類方法的具體使用不是很相同,關於登陸校驗的authenticate,Django在使用他們的時候,會遍歷所有的auth backends,一旦發現有一個backend校驗通過,即返回User對象,那么將會停止下面backend的校驗,並且將校驗成功的backend綁定在該用戶上放入session中,此后如果再次調用該方法,那么將會使用session中的backend進行校驗,而不再遍歷所有backend了。
而關於許可,一個用戶所擁有的perm是所有backends所返回的perm。
最后,我們要提醒一下,雖然has_perm的最后一個參數是一個obj,看上去像是支持每個對象級別的權限校驗,而事實上,Django只是在架構和接口上面支持了對象級別的權限校驗,但是並沒有實現。這意味着,所有關於對象權限的校驗方法返回值都是False或者是空列表。因此,如果需要實現Object級別的權限控制,需要自己寫或者使用第三方擴展來實現。具體點就是將會接受obj和user_obj,對於每一個auth方法會返回一個關於該用戶針對於該對象的一個權限控制結果。
總結
以上的5篇文章,詳細闡述說明了Django的簡潔而強大的權限認證系統,結合django admin site,我們可以很容易的進行權限的定義,分配,使用。
通過User,Permission,Group這三個模型,和Django的Authentication backends。實現了這套Django的簡潔版本權限認證。並且通過TemplateProcessor和RequestContext在模版系統中有着方便的使用,讓我們可以在界面中通過權限來控制提供給某個用戶的顯示。
但是,美中不足的是Django並沒有實現對象級別的權限控制。比方說在論壇系統中,只有管理員和帖子的發布者才有對該帖子對象的修改權限,這就是對象級別而非模型級別的權限控制。因此,我們需要自己實現對象級別的權限控制。依靠我們對django核心auth系統的掌握,我們可以很容易的開發或者引用第三方提供的Object level auth。具體關注接下來的博文。