Django Authentication 使用者認證系統完全指南 | Django 教學

2026/06/18 2026/05/24
Django Authentication 使用者認證系統完全指南 | Django 教學

幾乎所有的 Web 應用程式都需要處理使用者身份驗證。Django 內建了一套功能完善的 Authentication(認證) 系統,從 User 模型登入登出 函數、到 密碼管理密碼重設 流程,全部開箱即用。本篇將帶你全面了解 Django 認證系統的每個環節,並實作一套完整的使用者認證功能。

Django 認證系統概覽

Django 的認證系統由 django.contrib.auth 模組提供,它整合了 認證(Authentication)授權(Authorization) 兩大功能:

  • 認證(Authentication):驗證「你是誰」——使用者是否為合法帳號
  • 授權(Authorization):決定「你能做什麼」——使用者擁有哪些權限

要使用認證系統,確認 settings.py 中已包含以下設定:

# settings.py
INSTALLED_APPS = [
    'django.contrib.auth',            # 認證框架核心
    'django.contrib.contenttypes',    # 權限系統依賴
    # ...
]

MIDDLEWARE = [
    'django.contrib.sessions.middleware.SessionMiddleware',       # Session 支援
    'django.contrib.auth.middleware.AuthenticationMiddleware',    # 將 user 掛到 request
    # ...
]

認證系統的核心元件:

元件說明
User內建使用者模型,提供帳號、密碼、Email 等欄位
PermissionModel 層級的權限(add、change、delete、view)
Group權限的集合,可批次指派給使用者
Session基於 Session 的登入狀態維護機制

User 模型欄位

Django 的內建 User 模型(django.contrib.auth.models.User)提供了以下欄位:

欄位類型說明
usernameCharField使用者名稱(唯一)
passwordCharField雜湊後的密碼
emailEmailField電子郵件
first_nameCharField
last_nameCharField
is_activeBooleanField帳號是否啟用
is_staffBooleanField是否可登入 Admin 後台
is_superuserBooleanField是否為超級使用者
last_loginDateTimeField最後登入時間
date_joinedDateTimeField帳號建立時間

常用的方法:

from django.contrib.auth.models import User

# 建立一般使用者
user = User.objects.create_user(
    username='alice',
    email='alice@example.com',
    password='secure_password123'  # 自動雜湊處理
)

# 建立超級使用者
admin = User.objects.create_superuser(
    username='admin',
    email='admin@example.com',
    password='admin_password123'
)

# 檢查使用者屬性
user.is_authenticated  # True(已登入的使用者永遠為 True)
user.is_anonymous      # False
user.get_full_name()   # 回傳 "first_name last_name"
user.get_short_name()  # 回傳 "first_name"

authenticate / login / logout 函數

Django 提供三個核心函數來處理認證流程,它們位於 django.contrib.auth 模組中。

authenticate()——驗證帳號密碼

from django.contrib.auth import authenticate

# 驗證使用者憑證
user = authenticate(request, username='alice', password='secure_password123')

if user is not None:
    # 驗證成功,user 是一個 User 物件
    print(f"歡迎,{user.username}!")
else:
    # 驗證失敗(帳號不存在或密碼錯誤)
    print("帳號或密碼錯誤")

authenticate() 會依序嘗試 settings.pyAUTHENTICATION_BACKENDS 列出的所有認證後端,任一成功即回傳 User 物件。

login()——建立登入狀態

from django.contrib.auth import login

# 驗證成功後,建立 Session 登入狀態
login(request, user)
# 此時 Session 中已記錄使用者資訊
# 後續請求的 request.user 會自動指向此使用者

login() 做的事情是:將 User 的 ID 寫入 Session,並在 Response 中設定 sessionid Cookie,後續請求就能透過 Cookie 識別使用者身份。

logout()——登出

from django.contrib.auth import logout

# 清除 Session,登出使用者
logout(request)
# 此時 request.user 會變成 AnonymousUser

完整登入 View 範例

# views.py
from django.contrib.auth import authenticate, login, logout
from django.shortcuts import render, redirect

def login_view(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']

        # 第一步:驗證帳號密碼
        user = authenticate(request, username=username, password=password)

        if user is not None:
            # 第二步:建立登入狀態
            login(request, user)
            # 第三步:重導向到原始頁面或首頁
            next_url = request.GET.get('next', '/')
            return redirect(next_url)
        else:
            return render(request, 'accounts/login.html', {
                'error': '帳號或密碼錯誤'
            })

    return render(request, 'accounts/login.html')

def logout_view(request):
    if request.method == 'POST':
        logout(request)
        return redirect('login')
    return redirect('/')

@login_required 裝飾器

@login_required 是最常用的認證裝飾器,它會在 View 執行前自動檢查使用者是否已登入。未登入的使用者會被重導向到登入頁面。

from django.contrib.auth.decorators import login_required

@login_required
def dashboard(request):
    """只有已登入的使用者才能存取此頁面"""
    return render(request, 'accounts/dashboard.html', {
        'user': request.user
    })

# 自訂登入頁面 URL
@login_required(login_url='/custom-login/')
def profile(request):
    return render(request, 'accounts/profile.html')

重導向行為:

  1. 未登入使用者造訪 /dashboard/
  2. 被重導向到 LOGIN_URL(預設 /accounts/login/),URL 帶有 ?next=/dashboard/
  3. 使用者登入成功後,自動跳回 /dashboard/

settings.py 中設定相關的重導向 URL:

# settings.py
LOGIN_URL = '/accounts/login/'            # 未登入時重導向的目標
LOGIN_REDIRECT_URL = '/dashboard/'        # 登入成功後的預設重導向
LOGOUT_REDIRECT_URL = '/'                 # 登出後的重導向目標

在 CBV 中使用 LoginRequiredMixin

如果你使用 Class-Based Views(CBV) ,可以使用 LoginRequiredMixin

from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import TemplateView

class DashboardView(LoginRequiredMixin, TemplateView):
    template_name = 'accounts/dashboard.html'
    login_url = '/accounts/login/'  # 可選,預設使用 settings.LOGIN_URL

注意:LoginRequiredMixin 必須放在 第一個 繼承位置,才能正確攔截未登入的請求。


LoginView / LogoutView CBV

Django 提供了內建的 LoginViewLogoutView ,讓你不用自己寫認證邏輯,只需要設定 URL 和模板即可。

LoginView

# urls.py
from django.contrib.auth.views import LoginView

urlpatterns = [
    path('accounts/login/', LoginView.as_view(
        template_name='accounts/login.html',     # 自訂模板
        redirect_authenticated_user=True,         # 已登入使用者自動跳轉
    ), name='login'),
]

對應的模板只需要提供一個 form:

{# templates/accounts/login.html #}
<h2>登入</h2>

{% if form.errors %}
  <p style="color: red;">帳號或密碼錯誤,請重試。</p>
{% endif %}

<form method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">登入</button>
</form>

LogoutView

# urls.py
from django.contrib.auth.views import LogoutView

urlpatterns = [
    path('accounts/logout/', LogoutView.as_view(
        next_page='/',  # 登出後重導向到首頁
    ), name='logout'),
]
{# 在模板中使用 POST 請求登出 #}
<form method="post" action="{% url 'logout' %}">
  {% csrf_token %}
  <button type="submit">登出</button>
</form>

Django 4.1 以後,LogoutView 預設只接受 POST 請求,不再支援 GET 登出,這是為了防止 CSRF 攻擊(跨站請求偽造)


密碼管理

Django 提供了完善的密碼管理機制,包括密碼的設定、驗證與雜湊處理。

set_password() 與 check_password()

from django.contrib.auth.models import User

user = User.objects.get(username='alice')

# 設定新密碼(自動雜湊,不是存明碼)
user.set_password('new_secure_password')
user.save()  # 記得要呼叫 save()

# 驗證密碼是否正確
user.check_password('new_secure_password')   # True
user.check_password('wrong_password')         # False

重要提醒:永遠不要直接賦值 user.password = '...',這樣會存入明碼。必須使用 set_password() 方法,它會自動進行雜湊處理。

密碼雜湊機制

Django 使用 PBKDF2 演算法作為預設的密碼雜湊方式,儲存格式為 <algorithm>$<iterations>$<salt>$<hash>

pbkdf2_sha256$600000$randomsalt$hashed_value_here

你可以在 settings.py 中自訂使用的雜湊演算法:

# settings.py
PASSWORD_HASHERS = [
    # 第一個為新密碼的預設演算法
    'django.contrib.auth.hashers.PBKDF2PasswordHasher',       # 預設
    'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
    'django.contrib.auth.hashers.Argon2PasswordHasher',        # 推薦(需 pip install argon2-cffi)
    'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',  # 需 pip install bcrypt
]

密碼驗證器

Django 內建四個密碼驗證器,確保使用者設定的密碼符合安全標準:

# settings.py
AUTH_PASSWORD_VALIDATORS = [
    {
        # 密碼不能與使用者屬性(username、email 等)太相似
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        # 密碼最短長度
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        'OPTIONS': {'min_length': 8},
    },
    {
        # 密碼不能是常見弱密碼(內建 20,000 組常見密碼清單)
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        # 密碼不能全部是數字
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

密碼重設流程

Django 內建完整的密碼重設(Password Reset)流程,由四個 View 組成。你只需設定 URL 與模板,無需自己處理 token 產生與驗證邏輯。

設定四個 URL

# urls.py
from django.contrib.auth import views as auth_views

urlpatterns = [
    # 第一步:輸入 Email 頁面
    path('password-reset/', auth_views.PasswordResetView.as_view(
        template_name='accounts/password_reset.html',
        email_template_name='accounts/password_reset_email.html',
        subject_template_name='accounts/password_reset_subject.txt',
        success_url='/password-reset/done/',
    ), name='password_reset'),

    # 第二步:Email 已寄出的提示頁面
    path('password-reset/done/', auth_views.PasswordResetDoneView.as_view(
        template_name='accounts/password_reset_done.html',
    ), name='password_reset_done'),

    # 第三步:點擊連結後的重設表單頁面
    path('password-reset-confirm/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(
        template_name='accounts/password_reset_confirm.html',
        success_url='/password-reset-complete/',
    ), name='password_reset_confirm'),

    # 第四步:重設完成的提示頁面
    path('password-reset-complete/', auth_views.PasswordResetCompleteView.as_view(
        template_name='accounts/password_reset_complete.html',
    ), name='password_reset_complete'),
]

對應模板

{# templates/accounts/password_reset.html #}
<h2>重設密碼</h2>
<p>請輸入您的 Email,我們將寄送密碼重設連結。</p>
<form method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">寄送重設連結</button>
</form>
{# templates/accounts/password_reset_email.html(Email 內容模板)#}
您好 {{ user.get_username }}
請點擊以下連結重設您的密碼:
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}

此連結僅可使用一次,若您未要求重設密碼,請忽略此信件。
{# templates/accounts/password_reset_confirm.html #}
<h2>設定新密碼</h2>
{% if validlink %}
  <form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">確認新密碼</button>
  </form>
{% else %}
  <p>此重設連結已失效,請重新申請。</p>
{% endif %}

註冊功能實作

Django 沒有提供內建的註冊 View,但提供了 UserCreationForm 表單類別,讓你快速實作使用者註冊功能。

使用 UserCreationForm

# views.py
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import login
from django.shortcuts import render, redirect

def register_view(request):
    if request.method == 'POST':
        form = UserCreationForm(request.POST)
        if form.is_valid():
            # 儲存新使用者
            user = form.save()
            # 註冊成功後自動登入
            login(request, user)
            return redirect('dashboard')
    else:
        form = UserCreationForm()

    return render(request, 'accounts/register.html', {'form': form})

擴展 UserCreationForm 加入 Email 欄位

預設的 UserCreationForm 只有 username 和 password 欄位。若需要 Email 欄位,可以繼承並擴展:

# forms.py
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django import forms

class CustomUserCreationForm(UserCreationForm):
    email = forms.EmailField(
        required=True,
        help_text='請輸入有效的電子郵件地址'
    )

    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2']

    def clean_email(self):
        """檢查 Email 是否已被使用"""
        email = self.cleaned_data.get('email')
        if User.objects.filter(email=email).exists():
            raise forms.ValidationError('此 Email 已被註冊')
        return email

    def save(self, commit=True):
        user = super().save(commit=False)
        user.email = self.cleaned_data['email']
        if commit:
            user.save()
        return user
# views.py
from .forms import CustomUserCreationForm

def register_view(request):
    if request.method == 'POST':
        form = CustomUserCreationForm(request.POST)
        if form.is_valid():
            user = form.save()
            login(request, user)
            return redirect('dashboard')
    else:
        form = CustomUserCreationForm()

    return render(request, 'accounts/register.html', {'form': form})

對應的模板:

{# templates/accounts/register.html #}
<h2>建立帳號</h2>
<form method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">註冊</button>
</form>
<p>已有帳號?<a href="{% url 'login' %}">前往登入</a></p>

Session 安全性設定

認證系統依賴 Session 維護登入狀態,確保 Session 的安全性非常重要:

# settings.py
SESSION_COOKIE_HTTPONLY = True       # 防止 JavaScript 讀取 Cookie
SESSION_COOKIE_SECURE = True         # 只透過 HTTPS 傳送(生產環境)
SESSION_COOKIE_SAMESITE = 'Lax'     # 防止 CSRF 攻擊
SESSION_COOKIE_AGE = 1209600         # Session 有效期 14 天(單位:秒)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False  # 關閉瀏覽器後 Session 不失效

總結

Django 的 Authentication 系統功能完善且開箱即用,大幅降低了實作使用者認證的工作量。以下整理本篇的核心要點:

  1. 認證系統架構 整合了 User 模型、Permission、Group 與 Session,提供從登入到權限控制的完整解決方案
  2. authenticate / login / logout 三個核心函數各司其職——驗證憑證、建立登入狀態、清除 Session
  3. @login_required 裝飾器與 LoginRequiredMixin 讓存取控制變得簡單,搭配 LOGIN_URL 設定可自訂重導向行為
  4. LoginView / LogoutView 是 Django 內建的認證 CBV,只需設定模板和 URL 就能快速上線
  5. 密碼管理 透過 set_passwordcheck_password 處理,Django 自動進行雜湊,永遠不存明碼
  6. 密碼重設流程 由四個內建 View 組成,包含 token 產生與驗證,只需撰寫模板即可使用
  7. 註冊功能 透過 UserCreationForm 快速實作,可繼承擴展以加入自訂欄位

掌握了認證系統後,下一篇我們將深入探討 自訂使用者模型(Custom User Model) ,學習如何透過 AbstractUserAbstractBaseUser 打造符合業務需求的使用者模型。

BenZ Software Developer

熱愛技術的軟體開發者,在這裡分享程式開發經驗與學習筆記。

本週主打

AI 自動化入門包

你每天手動在做的那些煩事,其實 AI 可以自己跑。這份給你 10 個照著做就會的自動化工作流 + 50 個複製即用的提示詞,不用會寫程式。

看看這個產品 →