Django 之 auth 模塊


Django 內置一個 auth 模塊,幫助用戶實現注冊、登錄、注銷以及修改密碼等功能,幫助開發者省去了很多功夫。

auth 模塊

在創建模型時,Django內部會生成一個名為 auth_user 的數據表,用於存儲認證的用戶信息。

auth 模塊提供了一系列的方法,使用之前需要導入:

from django.contrib import auth

authenticate() 方法

提供用戶認證功能,驗證用戶名和密碼是否正確等。如驗證成功,則返回一個 User 對象。

from django.contrib import auth

def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')

         # 用戶認證,驗證用戶名、密碼是否正確,並返回一個 user 對象
         # username、password 字段對應 auth_user 表中相應字段
        user_obj = auth.authenticate(username=username, password=password)

login() 方法

實現用戶登錄功能,會在后台為登錄用戶生成 session 數據。

from django.contrib import auth
auth.login(request, user_obj)

from django.contrib.auth import login
login(request, user_obj)

接收兩個參數,第一個為 HTTPRequest 對象,以及一個認證過的用戶對象(即 authenticate() 認證過的用戶對象)。

from django.contrib import auth

def login(request):
    """登錄"""
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')

        # 用戶認證,驗證用戶名、密碼是否正確,並返回一個 user 對象
        user_obj = auth.authenticate(username=username, password=password)
        if user_obj:
            # 將驗證成功的用戶封裝到 request.user 對象中
            auth.login(request, user_obj)
            return redirect('home')
        else:
            return '錯誤信息'
    return render(request, 'login.html')

認證成功的用戶對象,執行 login() 方法,實現登錄功能,否則返回錯誤信息。

Tips

執行過 login() 方法的用戶對象,就能通過request.user 拿到當前登錄的用戶對象,從而取出用戶的相關信息,否則取得的將是一個匿名用戶對象 AnonymounsUser Object

login(request, user_obj)
# 獲得當前登錄用戶對象
user = request.user
# 獲得當前登錄用戶對象的用戶名
username = request.user.username

logout() 方法

該方法實現注銷功能,清除當前登錄用戶數據庫中的 session 數據,接收一個 HttpRequest 對象,無返回值。

from django.contrib import auth

def logout(request):
    """注銷"""
    auth.logout(request)
    # 注銷后重定向到登錄頁面
    return redirect('login')

is_authenticated 屬性

判斷當前用戶是否通過認證,為布爾值。

def home(request):
    """首頁"""
    ret = request.user.is_authenticated
    print(ret)      # True

login_required() 方法

auth 模板提供的一個裝飾器工具,能夠便捷地為某個視圖添加登錄校驗。

  • 若用戶沒有登錄,則默認會跳轉到 accounts/login/,並傳遞當前訪問 url 絕對路徑。
  • 自定義跳轉路徑,只需在 settings.py 中添加:
# 當用戶沒有登錄,訪問某個視圖時將會跳轉到登錄頁面
LOGIN_URL = '/login/'
from django.contrib.auth.decorators import login_required

# 添加裝飾器
@login_required
def home(request):
    """首頁"""

    return render(request, 'home.html')

當用戶訪問 home 頁面時,若沒有登錄則會跳轉到登錄頁面,否則返回 home 頁面。

用戶相關

上面介紹的都是關於登錄相關的,下面將介紹如何創建在 auth_user 中創建用戶,修改密碼,驗證密碼等。

create_superuser() 方法

該方法用於創建一個超級用戶,接收 username、password 兩個必要參數。效果與執行 python manage.py createsuperuser 等同。

from django.contrib.auth.models import User

user_obj = User.objects.create_superuser(username='用戶名',password='密碼',email='郵箱',...)

create_user() 方法

一般情況 create_superuser() 方法很少使用,最常使用的是create_user() 方法,它將會創建一個普通用戶,常應用於注冊視圖中。

創建用戶所需字段,應與 auth_user 數據表中字段對應。

from django.contrib.auth.models import User

def signup(request):
    # 創建新用戶
    user_obj = User.objects.create_user(username='lila', password='1234')

    return HttpResponse('創建成功')

Tips

新創建的用戶,保存在 auth_user數據表中的密碼是經過加密的。

check_password() 方法

檢查登錄用戶密碼是否正確,需要當前請求用戶的密碼。

from django.contrib.auth.models import User

def signup(request):
    # 創建新用戶
    user_obj = User.objects.create_user(username='lila', password='1234')
    
    ret = user_obj.check_password('123456')
    print(ret)      # False
    return HttpResponse('創建成功')

密碼正確返回 True,否則返回 False。

或者對當前請求的 user 對象校驗原密碼是否正確:

obj = request.user.check_password(raw_password='原始密碼')

set_password() 方法

該方法用於修改密碼,接收要新密碼作為參數,最后一定要執行 save() 方法保存,否則無效。

def set_password(request):
    """
    修改密碼,request.user 中封裝了已認證且執行了登錄功能的用戶對象
    :param request: 
    :return: 
    """
    request.user.set_password('12')
    password = request.user.password
    request.user.save()
    print(password)

    return HttpResponse('修改成功')

修改密碼示例

該示例僅適用於已登錄的用戶,在內部修改密碼,未登錄的用戶將跳轉到登錄頁面。

from django.shortcuts import render, redirect, HttpResponse
from django.contrib.auth.decorators import login_required

@login_required
def set_password(request):
    """
    修改密碼,request.user 中封裝了已認證且執行了登錄功能的用戶對象
    :param request:
    :return:
    """
    user = request.user
    ret = {'message': None}
    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:
                ret['message'] = '新密碼不能為空'
            
            elif new_password != repeat_password:
                ret['message'] = '兩次密碼輸入不一致'
            else:
                user.set_password(new_password)
                user.save()
                return redirect('login')
        else:
            ret['message'] = '原密碼不正確'
    return render(request, 'set_password.html', ret)

auth 模塊拓展

由於 auth 模板中 auth_user 數據表字段是固定的,因此當我們使用 auth 模塊,想要添加額外的字段時,就需要對其進行拓展。

拓展方法有兩種:

  • 模型中新增一個表,與 auth_user 表一對一關聯
  • 繼承內置的 AbstractUser 類:常用
  1. 模型 models.py 中新建一個類,繼承自 AbstractUser
from django.contrib.auth.models import User, AbstractUser   # 導入 AbstractUser 類


class UserInfo(AbstractUser):
    """
    繼承 AbstractUser
    新增字段:phone、addr
    """
    phone = models.CharField(max_length=11, verbose_name='手機號碼')
    addr = models.CharField(max_length=128, verbose_name='家庭地址')

  1. 配置 settings.py

新增的類繼承 AbstractUser ,拓展后將會覆蓋 auth_user 表,因此需要配置 settings,使默認認證知道要使用哪種表認證。

# settings.py
# 在最后添加如下代碼
AUTH_USER_MODEL = 'app名.新增的類名'

AUTH_USER_MODEL = 'app.UserInfo'    # 示例

  1. 遷徙數據表
python manage.py makemigrations
python manage.py migrate

  1. 創建用戶

拓展 auth 模塊后,使用的不再是原來 auth_user 表,而是新表 app.UserInfo 表,因此在創建用戶時應該注意。

# 拓展之前
from django.contrib.auth.models import User
user_obj = User.objects.create_user(username='lila', password='1234')

# 拓展之后
from app.models import UserInfo
user_obj = UserInfo.objects.create_user(username='lila', password='1234')

Tips

  • 若已經遷徙了模型,拓展 auth 模塊時,需要將 migrations 文件夾下文件(如:0001_initial.py文件刪除),否則會報 ValueError: Related model u'app.model' cannot be resolved
  • 若還沒有遷徙模型,那么正常執行即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM