一、auth模塊
from django.contrib import auth
django.contrib.auth中提供了許多方法,這里主要介紹其中的三個:
authenticate()
提供了用戶認證,即驗證用戶名以及密碼是否正確,一般需要username,password兩個關鍵字參數。
如果認證信息有效,會返回一個User對象。authenticate()會在User對象上設置一個屬性來標識后端已經認證了該用戶,且該信息在后續的登錄過程中是需要的。
user = auth.authenticate(username=username, password=pwd) if user: pass # 內置的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 CustomModelBackend(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.CustomModelBackend', ] # 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:
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(login_url=settings.LOGIN_URL)
def my_view(request): ...
若用戶沒有登錄,則會跳轉到django默認的登錄URL '/accounts/login/ ' (這個值可以在settings.py文件中通過LOGIN_URL進行修改)。
並傳遞 當前訪問url的絕對路徑 (登陸成功后,會重定向到該路徑)。
以上適用於方法視圖,至於類視圖則使用Mixin混入,可參考本站博客或Django官網。
創建用戶
使用 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部署 ]