首先的兩個中間件
sessions.middleware.SessionMiddleware’, 和 AuthenticationMiddleware 中間件再創建項目的時候會自動註冊到系統中的
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.transaction.TransactionMiddleware',
)
有了這兩個中間件,在view中,我們就可以使用request.user獲取當前的登陸用戶User對象。如果當前用戶沒有登陸,那麼request.user將會是我們之前所說的AnonymousUser對象。我們可以用User對象的is_authenticated()方法將這兩者區分開來:
if request.user.is_authenticated():
# 針對驗證用戶.
else:
# 對於匿名未登錄用戶
登陸一個用戶
需要兩個函數:authenticate(username,password)和login(request,user),位於django.contrib.auth模塊中;這兩個方法需要結合使用,
- authenticate(username,password)函數需要兩個參數username,password,如果校驗通過則返回User對象,如果校驗不通過返回None,例如:
from django.contrib.auth import authenticate
user = authenticate(username='john', password='secret')
if user is not None:
if user.is_active:
print "You provided a correct username and password!"
else:
print "Your account has been disabled!"
else:
print "Your username and password were incorrect."
- .login()方法接受兩個參數,第一個是request對象,第二個是驗證後的user對象。login方法使用SessionMiddleware將userID存入session當中。注意,在用戶還未登錄的時候,也存在着匿名用戶的Session,在其登陸之後,之前在匿名Session中保留的信息,都會保留下來。這兩個方法要結合使用,而且必須要先調用authenticate(),因爲該方法會User的一個屬性上紀錄該用戶已經通過校驗了,這個屬性會被隨後的login過程所使用,例如:
rom django.contrib.auth import authenticate, login
def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
# 跳轉到成功頁面.
else:
# 返回一個無效帳戶的錯誤
else:
# 返回登錄失敗頁面。
另外的登錄方法
也可以不用authenticate()進行特定於一個用戶的身份校驗,直接使用和User無關的幾個函數進行密碼相關的校驗,在Django1.4中以及新版本中提供以下方法,位於模塊django.contrib.auth.hashers:
check_password(password,encoded):第一個參數是明文密碼,第二個參數是加密過的密碼。如果通過校驗返回True,不通過返回False;
make_password(password[,salt,hashers]):根據給定的明文密碼,salt,和Django支持的加密算法,返回一個加密的密碼。如果password提供的值爲None,那麼該返回值將永遠通不過check_password()方法。這個返回值是一個特定的約定值,目前是'!';
is_password_usable(encoded_password):判斷是否給定字符串是一個hashed密碼,有機會通過check_password()函數的校驗。
登出(log out)一個用戶
我們使用django.contrib.auth.logout函數來登出用django.contrib.auth.login函數登入的用戶。
logout(requet)
函數只有一個參數,就是request。沒有返回值,而且即使當前用戶沒有登陸也不會拋出任何異常。
例子:
from django.contrib.auth import logout
def logout_view(request):
logout(request)
# 重定向到成功登出界面
注意:
這個方法,會將存儲在用戶session的數據全部清空,這樣避免有人用當前用戶的瀏覽器登陸然後就可以查看當前用戶的數據了,回想一下login會保留anonymous用戶的session數據。如果需要將一些東西加入到登出之後的用戶session,那麼需要在logout方法調用之後再進行。
Login和Logout的兩個signals
Django的signal體系是一套簡單實用的事件定義、事件產生、事件監聽、事件處理框架,具體可以參看Django關於signal的文檔。在登陸和登出這兩個重要的點上,提供了兩個signal:
django.contrib.auth.signals.user_logged_in
django.contrib.auth.signals.user_logged_out
有三個參數會隨singal傳過來:
sender:user的class,如果是logout事件該值有可能是None如果用戶根本就沒有驗證通過。
request:HttpRequest對象
user:user對象,如果是logout事件該值有可能是None如果用戶根本就沒有驗證通過。
一個經常性的簡單需求就是控制某些view(struts中叫做action方法)只對登陸用戶開放,如果未登錄用戶請求該view則跳轉到登錄界面讓其登陸。要做到這一點,我們可以這樣做:
from django.http import HttpResponseRedirect
def my_view(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/login/?next=%s' % request.path)
# ...
也可以這樣做,返回一個錯誤的頁面:
def my_view(request):
if not request.user.is_authenticated():
return render_to_response('myapp/login_error.html')
# ...
更爲優雅的方式是用decorator:
django.contrib.auth.decorators.login_required([redirect_field_name=REDIRECT_FIELD_NAME,login_url=None])
login_required()裝飾器函數做了以下事情:
如果當前用戶沒有登陸,跳轉到settings.LOGIN_URL,並傳遞當前的絕對路徑到URL請求參數中,例如:/accounts/login/?next=/polls/3/
如果當前用戶已經登陸了,執行view方法。在view中的方法可以認爲當前用戶已經登陸了。
login_required方法接受兩個參數:
redirect_field_name:默認值是next。用來定義登陸成功之後的跳回之前訪問界面的url。
login_url:默認值是settings.LOGIN_URL。用來指定登陸界面的url。如果不傳入改參數,就需要確保settings.LOGIN_URL的值是正確設置的。
沒有參數的login_required裝飾器使用方法:
from django.contrib.auth.decorators import login_required
@login_required
def my_view(request):
...
傳遞參數的方法:
from django.contrib.auth.decorators import login_required
@login_required(redirect_field_name='my_redirect_field')
def my_view(request):
...
from django.contrib.auth.decorators import login_required
@login_required(login_url='/accounts/login/')
def my_view(request):
...
以上就是Django提供的用於完成login和logout相關的一些API支持,使用他們可以很好的對用戶進行認證了,也就是說用戶是誰系統已經搞清楚了,接下來就是更細粒度的判斷,判斷此人究竟能做些什麼,也就是Permission許可的使用了。