一. Django預設使用者認證系統
Django 認證提供了實現認證(authentiaction)和授權(authorization)兩種功能的使用者認證系統–auth 使用的儲存表auth_user
參考文件點這裡
Django使用者認證系統它處理使用者賬號、組、許可權以及基於cookie的使用者會話。
- Django認證系統同時處理認證和授權:
- 認證:驗證一個使用者是否可用於賬號登入。
- 授權:授權決定一個通過了認證的使用者被允許做什麼。
- Django認證系統包含的內容:
- 使用者:使用者模型類、使用者認證。
- 許可權:標識一個使用者是否可以做一個特定的任務。
- 組:對多個具有相同許可權的使用者進行統一管理。
- 密碼:一個可配置的密碼雜湊系統,設定密碼、密碼校驗。
主要模組:
from django.contrib import auth //包含身份驗證框架的核心及其預設模型 from django.contrib import contenttypes //是Django內容型別系統,它允許許可權與你建立的模型關聯。
模組詳解:
from django.contrib import auth //確保你的每個 Django 模型被建立時有四個預設許可權:新增、修改、刪除和檢視 from django.contrib.auth.models import User //user物件 from django.contrib.auth import authenticate // authenticate驗證使用者 from django.contrib.auth.models import Group //對使用者進行分類的通用方法
user物件的許可權操作:
django.contrib.auth.models.User” 物件有兩個多對多欄位:groups
和user_permissions
可以通過user_permissions
屬性將許可權分配給user
,或通過permissions
屬性分配給group
操作:
myuser.groups.set([group_list])
myuser.groups.add(group, group, ...)
myuser.groups.remove(group, group, ...)
myuser.groups.clear()
myuser.user_permissions.set([permission_list])
myuser.user_permissions.add(permission, permission, ...)
myuser.user_permissions.remove(permission, permission, ...)
myuser.user_permissions.clear()
我們看一下基本如何使用
二. 使用者認證系統實現例項
主要用到的幾個方法:
- create_user 建立使用者
- authenticate 驗證登入
- login 記住使用者的登入狀態
- logout 退出登入
- is_authenticated 判斷使用者是否登入
login_required 判斷使用者是否登入的裝飾器
1. 建立使用者:
User 物件的主要屬性有 username, password, email, first_name, last_name
1.1 普通的建立使用者
from django.contrib.auth.models import User
user = User.objects.create_user('yym', 'yym@yiyumo.com', 'yympassword')
~ 建立超級使用者指令 python manage.py createsuperuser –username=yym --email=yym@yym.com ~
1.2 更改密碼
from django.contrib.auth.models import User
u = User.objects.get(username='yym')
u.set_password('new password')
u.save()
~ 更改密碼指令 python manage.py changepassword username ~
2. 驗證使用者
使用
authenticate()
來驗證使用者。它使用username
和password
作為引數來驗證,對每個身份驗證後端進行檢查。如果後端驗證有效,則返回一個User 物件。如果後端引發PermissionDenied
錯誤,將返回None
from django.contrib.auth import authenticate
user = authenticate(username='john', password='secret')
if user is not None:
# A backend authenticated the credentials
else:
# No backend authenticated the credentials
3. 許可權
當 INSTALLED_APPS 設定了 django.contrib.auth 時,它將確保你的每個 Django 模型被建立時有四個預設許可權:新增、修改、刪除和檢視
3.1 建立許可權
from car.models import UseCar
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
# 為車輛模型建立可釋出接單的許可權
content_type = ContentType.objects.get_for_model(UseCar)
permission = Permission.objects.create(
codename='can_publish',
name='Can Publish Posts',
content_type=content_type,
)
3.2 許可權快取
第一次需要獲取使用者物件的許可權檢查時,ModelBackend
才會快取它們的許可權
from django.contrib.auth.models import Permission, User
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import get_object_or_404
from car.models import UseCar
def user_gains_perms(request, user_id):
user = get_object_or_404(User, pk=user_id)
# any permission check will cache the current set of permissions
user.has_perm('car.change_usecar')
content_type = ContentType.objects.get_for_model(UseCar)
permission = Permission.objects.get(
codename='change_usecar',
content_type=content_type,
)
user.user_permissions.add(permission)
# Checking the cached permission set
user.has_perm('car.change_usecar') # False
# Request new instance of User
# Be aware that user.refresh_from_db() won't clear the cache.
user = get_object_or_404(User, pk=user_id)
# Permission cache is repopulated from the database
user.has_perm('car.change_usecar') # True
...
4. Web 請求的認證
4.1 web請求的驗證
Django 使用 sessions 和中介軟體將身份驗證系統掛接到請求物件中
它們在每次請求中都會提供request.user
屬性。如果當前沒有使用者登入,這個屬性將會被設定為AnonymousUser
,否則將會被設定為User
例項。
使用user
的屬性is_authenticated
來區分 使用者是否已通過身份驗證
使用user
的屬性is_anonymous
來區分User和AnonymousUser 物件
if request.user.is_authenticated:
user
...
else:
pass
4.2 使用者的登入
將已驗證的使用者想附加到當前會話(session)中將通過 login()
函式完成
from django.contrib.auth import authenticate, login
def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password) //驗證
if user is not None:
login(request, user) //登入
# Redirect to a success page.
...
else:
# Return an 'invalid login' error message.
...
4.3 使用者的登出
將已驗證的使用者想從當前會話(session)中將刪除通過 logout()
函式完成
from django.contrib.auth import logout
def logout_view(request):
logout(request)
實際專案開發中常會遇到以下幾個問題(關於這些問題之後會詳細討論):
- 由於預設的user通常在實際開發中並不能滿足我們的需求,我們通常會繼承User表進行擴充以及擴充之後使用者建立時需注意密碼明文等問題。
- 現實中 由於session的一些缺點所以一般專案中會採用基於token的鑑權機制。
- 伺服器來說,必須儲存所有線上使用者的session,那麼這就佔用了很大的資源(cpu,記憶體),嚴重影響伺服器的效能.
- 擴充套件伺服器做叢集,但是同時也出現了分散式session的問題
- django 自帶的許可權機制無法滿足專案需求 會擴充許可權設定
session機制原理圖:
token機制原理圖:
本作品採用《CC 協議》,轉載必須註明作者和本文連結