Django - 用戶認證
今天我們將學習如何在 Django 中實現用戶認證功能,包括用戶註冊、登入、登出,以及使用者授權。這是任何現代應用程式的核心功能,對於加強應用程式的安全性非常重要。
課程目標
- 瞭解 Django 預設的用戶認證系統。
- 實現用戶註冊、登入與登出功能。
- 在視圖中使用裝飾器進行授權檢查。
- 自訂用戶模型(如有必要)。
課程內容
1. Django 的用戶認證系統
Django 提供了一個強大的用戶認證框架,支持:
- 用戶模型(內建的
User
模型)。 - 登入、登出與密碼管理。
- 授權與群組權限。
1.1 添加應用
確保 INSTALLED_APPS
包含以下應用:
1
2
3
4
5
6
7
8
INSTALLED_APPS = [
# 其他應用...
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
1.2 URL 路由配置
確保中間件啟用了 AuthenticationMiddleware
和 SessionMiddleware
:
1
2
3
4
5
6
7
8
9
10
MIDDLEWARE = [
# 其他中間件...
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
2. 用戶註冊
2.1 表單設計
在 forms.py
中新增用戶註冊表單:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from django import forms
from django.contrib.auth.models import User
class UserRegisterForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput, label="密碼")
confirm_password = forms.CharField(widget=forms.PasswordInput, label="確認密碼")
class Meta:
model = User
fields = ['username', 'email', 'password']
def clean(self):
cleaned_data = super().clean()
password = cleaned_data.get("password")
confirm_password = cleaned_data.get("confirm_password")
if password != confirm_password:
raise forms.ValidationError("密碼與確認密碼不一致")
2.2 視圖實作
在 views.py
中新增註冊功能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from django.contrib.auth.models import User
from django.shortcuts import render, redirect
from .forms import UserRegisterForm
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.set_password(form.cleaned_data['password'])
user.save()
return redirect('login')
else:
form = UserRegisterForm()
return render(request, 'auth/register.html', {'form': form})
2.3 模板設計
templates/auth/register.html
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html>
<head>
<title>註冊</title>
</head>
<body>
<h1>用戶註冊</h1>
<form method="post">
{% csrf_token %} {{ form.as_p }}
<button type="submit">註冊</button>
</form>
<a href="{% url 'login' %}">已有帳戶?點此登入</a>
</body>
</html>
3. 用戶登入與登出
3.1 登入功能
在 views.py
中實作登入功能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from django.contrib.auth import authenticate, login
from django.contrib.auth.forms import AuthenticationForm
def user_login(request):
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return redirect('post_list')
else:
form = AuthenticationForm()
return render(request, 'auth/login.html', {'form': form})
3.2 登出功能
在 views.py
中實作登出功能:
1
2
3
4
5
from django.contrib.auth import logout
def user_logout(request):
logout(request)
return redirect('login')
3.3 模板設計
templates/auth/login.html
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html>
<head>
<title>登入</title>
</head>
<body>
<h1>用戶登入</h1>
<form method="post">
{% csrf_token %} {{ form.as_p }}
<button type="submit">登入</button>
</form>
<a href="{% url 'register' %}">還沒有帳戶?點此註冊</a>
</body>
</html>
4. 授權與權限控制
4.1 使用裝飾器
在需要授權的視圖中使用 @login_required
:
1
2
3
4
5
6
from django.contrib.auth.decorators import login_required
@login_required
def post_create(request):
# 只有登入的用戶才能新增文章
...
4.2 自訂權限
對於更細緻的權限管理,可以在模型中設定 permissions
:
1
2
3
4
5
6
class Post(models.Model):
...
class Meta:
permissions = [
('can_edit_post', 'Can Edit Post'),
]
在視圖中檢查權限:
1
2
3
4
5
from django.contrib.auth.decorators import permission_required
@permission_required('app_name.can_edit_post')
def post_update(request, post_id):
...
5. URL 配置
在 urls.py
中新增用戶相關路由:
1
2
3
4
5
6
7
8
from django.urls import path
from . import views
urlpatterns = [
path('register/', views.register, name='register'),
path('login/', views.user_login, name='login'),
path('logout/', views.user_logout, name='logout'),
]
6. 本日總結
- 實現了用戶註冊、登入與登出功能。
- 瞭解了授權與權限控制的基本概念。
- 使用 Django 的內建用戶認證系統快速構建安全的用戶管理功能。
作業
- 在 Blog 系統中,限制未登入用戶只能查看文章,無法新增、編輯或刪除文章。
- 為用戶新增「用戶頭像」功能,並允許用戶在註冊或個人設定中上傳圖片。
- 使用 Django 的群組功能,為不同群組的用戶分配不同的操作權限。
本文章以 CC BY 4.0 授權