Django REST Framework|@permission_classes指導手冊
更新日期: 2025 年 1 月 29 日
本文為 Django 登入註冊功能(後端)系列文,第 1 篇
- 新手指南|使用 Django 實現後端會員登入、註冊功能
- Django Rest Framework (DRF) 新手指南:為什麼選擇 DRF 建構 API?
- Django Rest Framework (DRF) 新手指南:用 ViewSets 快速構建 CRUD API
- 初學者指南:理解 Token 認證及其運作方式
- Django REST Framework (DRF) 認證方式、預設權限規則|新手指南
- Django Rest Framework 入門指南:如何正確處理 HTTP 狀態碼
- 初學者指南:深入了解 Django 的 create_user 方法
- 新手指南:深入了解 Django 的 authenticate 方法
- Django REST Framework|@permission_classes指導手冊 👈所在位置
- 使用 Postman 測試 Django 後端的註冊、登入與登出功能
在開發基於 Django REST Framework (DRF) 的 API 時,權限管理是保障數據安全的關鍵之一。
本文將帶您了解 @permission_classes([IsAuthenticated])
的作用、如何使用它,以及如果不設置權限可能帶來的影響。
適合新手理解和實踐的內容,讓我們一起深入探討!
為什麼權限控制很重要?
在開發 API 時,並非所有人都應該有權訪問每一個端點。
例如,登出功能只應該對已登錄的用戶開放,而不應被未經驗證的用戶使用。
Django REST Framework 提供了靈活的權限控制機制,其中 @permission_classes([IsAuthenticated])
是常用的一種方式。
如果忽略權限設置,可能導致未授權的訪問,進一步引發數據洩露或業務邏輯被惡意利用。
@permission_classes([IsAuthenticated])
是什麼?
@permission_classes
是一個裝飾器 (decorator),用來為特定的 API 視圖設置權限控制邏輯。
當您使用 [IsAuthenticated]
作為參數時,這表示只有已通過身份驗證的用戶(如通過 Token 或 Session 驗證)才能訪問該視圖。
具體來說:
- 已認證的用戶(已提供有效的身份憑據)可以訪問視圖。
- 未認證的用戶將收到 401 Unauthorized 回應,無法執行視圖中的任何操作。
IsAuthenticated
的作用
IsAuthenticated
是 DRF 內置的一個權限類別,其邏輯非常簡單:
- 如果用戶已經登錄(驗證成功),允許訪問。
- 如果用戶未登錄或身份驗證失敗,直接拒絕訪問。
有與沒有 @permission_classes([IsAuthenticated])
的差別
有 @permission_classes([IsAuthenticated])
的情況
當 API 視圖設置了 @permission_classes([IsAuthenticated])
,只允許已認證用戶訪問。
未認證用戶請求時將收到一個 401 Unauthorized 錯誤,並且不會執行視圖中的任何邏輯。
示例:設置登出功能
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework import status
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def logout_view(request):
request.user.auth_token.delete() # 刪除用戶的 Token
return Response({'message': '登出成功!'}, status=status.HTTP_200_OK)
- 用戶 A(已認證):可以訪問此端點,成功登出並刪除其 Token。
- 用戶 B(未認證):請求將直接返回 401 Unauthorized,API 保持安全。
沒有 @permission_classes([IsAuthenticated])
的情況
如果未設置任何權限裝飾器,視圖將默認允許所有人訪問,無論用戶是否已認證。
示例:未設置權限的登出功能
@api_view(['POST'])
def logout_view(request):
request.user.auth_token.delete() # 刪除用戶的 Token
return Response({'message': '登出成功!'}, status=status.HTTP_200_OK)
- 所有人都可以訪問:即使是未經身份驗證的用戶,也能調用這個 API。
- 如果未認證用戶請求,可能導致錯誤。
例如,request.user
將是一個匿名用戶 (AnonymousUser
),調用request.user.auth_token.delete()
時可能引發錯誤。 - 這樣的實現存在潛在安全風險,可能導致未授權的數據刪除或邏輯執行。
為什麼要使用 @permission_classes([IsAuthenticated])
?
確保 API 安全性
設置 @permission_classes([IsAuthenticated])
能確保僅已驗證的用戶訪問該端點。
這對於需要保護的業務邏輯和敏感數據至關重要。
避免未授權操作
在未設置權限時,匿名用戶可能執行高風險操作(如刪除 Token 或修改數據),導致數據洩露或邏輯錯誤。
使用標準化的權限機制
Django REST Framework 提供了標準化的權限類別,幫助開發者快速、準確地控制 API 訪問權限,減少手動實現權限控制的複雜性。
完整代碼示例對比
設置了權限的登出 API
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework import status
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def logout_view(request):
request.user.auth_token.delete()
return Response({'message': '登出成功!'}, status=status.HTTP_200_OK)
未設置權限的登出 API
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
@api_view(['POST'])
def logout_view(request):
request.user.auth_token.delete()
return Response({'message': '登出成功!'}, status=status.HTTP_200_OK)
差異點:
- 安全性:第一個例子保證只有已認證用戶能訪問,第二個例子允許任何人訪問。
- 錯誤處理:第一個例子避免匿名用戶引發的邏輯錯誤,第二個例子可能導致不可控的操作。
總結
在 Django REST Framework 中,@permission_classes([IsAuthenticated])
是一個簡單但強大的工具,用於保護 API 的訪問權限。
通過設置此權限,您可以:
- 確保只有合法用戶能訪問。
- 避免未授權的訪問和潛在的安全漏洞。
- 提升代碼的可讀性和標準化。