認證登陸
在進行使用者登陸驗證的時候,如果是自己寫代碼,就必須要先查詢資料庫,看使用者輸入的使用者名是否存在于資料庫中;
如果使用者存在于資料庫中,然後再驗證使用者輸入的密碼,這樣一來就要自己編寫大量的代碼。
事實上,Django已經提供了内置的使用者認證功能。
在使用
"python manage.py makemigrationss"
和 "python manage.py migrate"
遷移完成資料庫之後
根據配置檔案
settings.py
中的資料庫段生成的資料表中已經包含了6張進行認證的資料表,分别是 - auth_user
- auth_group
- auth_group_permissions
- auth_permission
- auth_user_groups
- auth_user_user_permissions
進行使用者認證的資料表為
auth_user
要使用Django自帶的認證功能,首先要導入
auth
子產品
from django.contrib import auth #導入auth子產品
django.contrib.auth
中提供了很多方法,我們常用的有三個方法:
authenticate()
提供了使用者認證,即驗證使用者名以及密碼是否正确,一般需要username和password兩個關鍵字參數
如果通過認證,
authenticate()
函數會傳回一個User對象。
authenticate()
函數會在User對象上設定一個屬性辨別,這個屬性辨別經過資料庫驗證使用者名及密碼。
當我們試圖登陸一個從資料庫中直接取出來不經過
authenticate()
的User對象時會報錯。
使用:
user=authenticate(username="uaername",password="password")
login(HttpResponse,user)
這個函數接受一個
HttpRequest
對象,以及一個通過
authenticate()
函數認證的User對象
login(request)登陸使用者
這個函數使用
Django
的
session
架構給某個已認證的使用者附加上
session_id
資訊。
from django.shortcuts import render,redirect,HttpResponse
from django.contrib.auth import authenticate,login
def auth_view(request):
username=request.POST.GET("usernmae") # 擷取使用者名
password=request.POST.GET("password") # 擷取使用者的密碼
user=authenticate(username=username,password=password) # 驗證使用者名和密碼,傳回使用者對象
if user: # 如果使用者對象存在
login(request,user) # 使用者登陸
return redirect("/index/")
else:
return HttpResponse("使用者名或密碼錯誤")
logout(request)登出使用者
HttpResponse
對象,無傳回值。
當調用該函數時,目前請求的session資訊全部被清除。
即使目前使用者沒有登陸,調用該函數也不會報錯。
from django.shortcuts import render,redirect,HttpResponse
from django.contrib.auth import authenticate,login,logout
def logout_view(request):
logout(request) # 登出使用者
return redirect("/index/")
user對象的is_authenticated()
要求:
- 使用者登陸後才能通路某些頁面
- 如果使用者沒有登陸就通路本應登陸才能通路的頁面時會直接跳轉到登陸頁面
- 使用者在登陸頁面登陸後,又會自動跳轉到之前通路的頁面
方法一:
def view1(request):
if not request.user.is_authenticated():
return redirect("/login/")
方法二:
使用Django的
login_requierd()
裝飾器
from django.contrib.auth.decorators import login_required
@login_required
def views(request):
pass
如果使用者沒有登陸,則會跳轉到Django預設的登陸URL的
"/accountss/login/"
login視圖函數可以在settings.py檔案中通過LOGIN_URL修改預設值
使用者登陸成功後,會重定向到原來的路徑。
user對象
User對象屬性:username,password為必填項
password用雜湊演算法儲存到資料庫中
- is_staff:判斷使用者是否擁有網站的管理權限
- is_active:判斷是否允許使用者登陸,設定為“False”時可以不用删除使用者來禁止使用者登陸
User對象的方法
is_authenticated()
如果是通過
auth
函數傳回的真實的User對象,傳回值則為True。這個方法檢查使用者是否已經通過了認證。
is_authenticated()
函數的傳回值為True時,表明使用者成功的通過了認證。
建立使用者
使用
create_user
輔助函數建立使用者
from django.contrib.auth.models import User
user=User.objects.create_user(username="username",password="password")
set_password(password)
使用這個方法來修改密碼
from django.contrib.auth.models import User
user=User.objects.get(username="username") # 擷取使用者對象
user.set_password(password="password") # 設定對象的密碼
user.save()
check_password(password)
使用者想修改密碼的時候,首先要讓使用者輸入原來的密碼。
如果使用者輸入的舊密碼通過密碼驗證,傳回True。
例子一,使用
set_password()
方法來修改密碼
from django.shortcuts import render,redirect,HttpResponse
from django.contrib.auth.models import User
def create_user(request):
msg=None
if request.method=="POST":
username=request.POST.get("username"," ") # 擷取使用者名,預設為空字元串
password=request.POST.get("password"," ") # 擷取密碼,預設為空字元串
confirm=request.POST.get("confirm_password"," ") # 擷取确認密碼,預設為空字元串
if password == "" or confirm=="" or username=="": # 如果使用者名,密碼或确認密碼為空
msg="使用者名或密碼不能為空"
elif password !=confirm: # 如果密碼與确認密碼不一緻
msg="兩次輸入的密碼不一緻"
elif User.objects.filter(username=username): # 如果資料庫中已經存在這個使用者名
msg="該使用者名已存在"
else:
new_user=User.objects.create_user(username=username,password=password) #建立新使用者
new_user.save()
return redirect("/index/")
return render(request,"login.html",{"msg":msg})
例子二,使用
login_required裝飾器
來修改密碼
from django.shortcuts import render,redirect,HttpResponse
from django.contrib.auth import authenticate,login,logout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
@login_required
def change_passwd(request):
user=request.user # 擷取使用者名
msg=None
if request.method=='POST':
old_password=request.POST.get("old_password","") # 擷取原來的密碼,預設為空字元串
new_password=request.POST.get("new_password","") # 擷取新密碼,預設為空字元串
confirm=request.POST.get("confirm_password","") # 擷取确認密碼,預設為空字元串
if user.check_password(old_password): # 到資料庫中驗證舊密碼通過
if new_password or confirm: # 新密碼或确認密碼為空
msg="新密碼不能為空"
elif new_password != confirm: # 新密碼與确認密碼不一樣
msg="兩次密碼不一緻"
else:
user.set_password(new_password) # 修改密碼
user.save()
return redirect("/index/")
else:
msg="舊密碼輸入錯誤"
return render(request,"change_passwd.html",{"msg":msg})