Django 自帶認證功能auth模塊和User對象的基本操作

一、auth模塊

from django.contrib import auth

django.contrib.auth中提供了許多方法,這裡主要介紹其中的三個:

authenticate()

提供了用戶認證,即驗證用戶名以及密碼是否正確,一般需要username,password兩個關鍵字參數。

如果認證信息有效,會返回一個 User 對象。authenticate()會在User 對象上設置一個屬性來標識後端已經認證了該用戶,且該信息在後續的登錄過程中是需要的。

user = auth.authenticate(username=username, password=pwd)
if user:
# 內置的login方法
# 生成Session數據,存一下user_id 然後把sessionid寫入Cookie
# 後續每一次請求來的時候,AuthenticationMiddleware中的process_request方法中
# 會取到user_id,進而取到user對象,然後添加到request.user屬性中 --> request.user = user
# 後續我們都可以通過request.user拿到當前的登陸用戶對象

重寫(自定義)登錄驗證後端authenticate()

例:實現用戶名或郵箱登錄驗證。

from django.contrib.auth.backends import ModelBackend
from django.db.models import Q

class CustomBackend(ModelBackend): # 繼承ModelBackend類,重寫authenticate()方法
"""
自定義用戶驗證後端:支持用戶名或郵箱登錄。
"""

def authenticate(self, request, username=None, password=None, **kwargs): # 參數username實際是用戶輸入的登錄賬號
try:
user = UserProfile.objects.get(Q(username=username) | Q(email=username))
if user.check_password(password):
return user
except Exception as e:
return None

然後別忘了在settings.py中配置該驗證後端:

AUTHENTICATION_BACKENDS = [yourfilepath.CustomBackend, ] # yourfilepath是該類的目錄

login(HttpRequest, user)  

登錄驗證。該函數接受一個HttpRequest對象,以及一個認證了的User對象。

此函數使用django的session框架給某個已認證的用戶附加上session id等信息。

from 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:
login(request, user)
# Redirect to a success page.
...
else:
# Return an invalid login error message.
...

logout(request)

登錄註銷用戶。 

from django.contrib.auth import logout

def logout_view(request):
logout(request)
# 調用auth內置的註銷方法

該函數接受一個HttpRequest對象,無返回值。當調用該函數時,當前請求的session信息會全部清除。該用戶即使沒有登錄,使用該函數也不會報錯。

二、User對象

User對象屬性:username,password(必填項)password用哈希演算法保存到資料庫

is_staff : 用戶是否擁有網站的管理許可權

is_active : 是否允許用戶登錄, 設置為"False",可以不用刪除用戶來禁止用戶登錄

is_authenticated()

如果是真正的 User 對象,返回值恆為 True 。 用於檢查用戶是否已經通過了認證。

通過認證並不意味著用戶擁有任何許可權,這個方法甚至也不檢查該用戶是否處於激活狀態,只是表明用戶成功的通過了認證。

這個方法很重要, 在後台用request.user.is_authenticated()判斷用戶是否已經登錄,如果true則可以向前台展示request.user.name。

場景:

  1. 用戶登陸後才能訪問某些頁面,
  2. 如果用戶沒有登錄就訪問該頁面的話直接跳到登錄頁面
  3. 用戶在跳轉的登陸界面中完成登陸後,自動訪問跳轉到之前訪問的地址

方法1:

def my_view(request):
if not request.user.is_authenticated():
return redirect(%s?next=%s % (settings.LOGIN_URL, request.path))

方法2:

django已經為我們設計好了一個用於此種情況的裝飾器:login_requierd(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None)

from django.contrib.auth.decorators import login_required

@login_required
def my_view(request):
...

若用戶沒有登錄,則會跳轉到django默認的 登錄URL /accounts/login/ (這個值可以在settings.py文件中通過LOGIN_URL進行修改)。

並傳遞 當前訪問url的絕對路徑 (登陸成功後,會重定向到該路徑)。

創建用戶

使用 create_user 輔助函數創建用戶:

from django.contrib.auth.models import User
user = User.objects.create_user(username=,password=,email=)

密碼檢查

check_password(password)

用戶需要修改密碼的時候,首先要讓其輸入原來的密碼 ,如果給定的值通過了密碼檢查,返回 True

修改密碼

使用 auth.hashers.make_password(password) 來修改密碼

user = User.objects.get(username=)
user.password = auth.hashers.make_password(password=123)  # 修改密碼,auth模塊自動將明文轉成密文
user.save()  # 修改密碼一定要保存

修改密碼簡單示例

from django.contrib.auth import hashers

@login_required
def set_password(request):
user = request.user
err_msg =
if request.method == POST:
old_password = request.POST.get(old_password, )
new_password = request.POST.get(new_password, )
repeat_password = request.POST.get(repeat_password, )
# 檢查舊密碼是否正確
if user.check_password(old_password):
if not new_password:
err_msg = 新密碼不能為空
elif new_password != repeat_password:
err_msg = 兩次密碼不一致
else:
user.password = hashers.make_password(new_password)
user.save()
return redirect("/login/")
else:
err_msg = 原密碼輸入錯誤
content = {
err_msg: err_msg,
}
return render(request, set_password.html, content)

三、認證進階:自定義auth User模型

這內置的auth_user表這麼好用,但是我在項目中沒法直接使用啊!比如,我想要加一個存儲用戶手機號的欄位,怎麼辦?

聰明的你可能會想到新建另外一張表然後通過一對一和內置的auth_user表關聯,這樣雖然能滿足要求但是有沒有更好的實現方式呢?

答案是當然有了。

我們可以通過繼承內置的auth_user表的對應的類,來定義一個自己的ORM類:

from django.contrib.auth.models import AbstractUser
class UserInfo(AbstractUser):    # 繼承AbstractUser類
"""
用戶信息表
"""
nid = models.AutoField(primary_key=True)
phone = models.CharField(max_length=11, null=True, unique=True)

def __str__(self):
return self.username

注意!!!

按上面的方式擴展了內置的auth_user表之後,一定要在settings.py中告訴Django,我現在使用我新定義的UserInfo表來做用戶認證。寫法如下:

# 引用Django自帶的User表,繼承使用時需要設置
AUTH_USER_MODEL = "app名.UserInfo"

如何設置默認的登錄頁面是什麼?

LOGIN_URL= "默認的頁面url"

此文章引自博客園,如有侵權,立即刪除

Django 自帶認證功能auth模塊和User對象的基本操作


推薦閱讀:

TAG:模塊 | Python | Django(框架) |