嘿,伙计!是不是曾被Django的认证系统绕得头晕眼花?就像第一次走进一家神秘咖啡店,店员问你:“要注册会员吗?只有会员才能喝限定款哦!” —— 用户认证和权限就是Django世界的“会员制度”。今天,咱们用一杯咖啡的时间,把用户相关的API从零到一彻底搞明白!
一、为什么需要用户认证和权限?
想象一下:你开了家网红咖啡店,顾客可以直接推门而入(无认证),但很快发现有人偷喝限量版咖啡。于是你推出会员卡(认证系统),又发现普通会员抢了VIP的专属座位。这时候,权限控制出场了——金卡会员才能上二楼,银卡只能在一楼溜达。
在Django中,用户认证(Authentication)解决“你是谁”,权限(Permission)决定“你能做什么”。接下来,咱们用代码搭建这个“咖啡店会员系统”!
二、搭建项目基础环境
1. 初始化项目
假设你已安装Django(还没装?快去pip install django!)。创建项目和应用:
django-admin startproject auth_api
cd auth_api
python manage.py startapp users
2. 配置设置
在settings.py中注册应用并设置认证模型:
INSTALLED_APPS = [
...
'rest_framework',
'rest_framework.authtoken', # 用于Token认证
'users',
]
# 使用Django自带的User模型,但建议实际项目中自定义
AUTH_USER_MODEL = 'auth.User'
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated', # 默认需要登录
],
}
三、设计用户模型:给用户“发会员卡”
Django自带的User模型就像基础会员卡,包含用户名、密码、邮箱等字段。但如果你想记录会员的“咖啡口味偏好”,就需要自定义模型:
# users/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
phone = models.CharField(max_length=15, blank=True)
birth_date = models.DateField(null=True, blank=True)
vip_level = models.IntegerField(default=1) # 1-银卡, 2-金卡
def __str__(self):
return f"{self.username} (Lv{self.vip_level})"
别忘了在settings.py中修改:AUTH_USER_MODEL = 'users.CustomUser',然后运行makemigrations和migrate。
四、构建用户API:注册、登录、查询
1. 序列化器:数据的“咖啡模具”
序列化器就像把咖啡豆磨成粉的模具,定义数据如何转换:
# users/serializers.py
from rest_framework import serializers
from django.contrib.auth import authenticate
from .models import CustomUser
class UserRegistrationSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True)
class Meta:
model = CustomUser
fields = ('username', 'password', 'email', 'phone', 'vip_level')
def create(self, validated_data):
user = CustomUser.objects.create_user(**validated_data)
return user
class UserLoginSerializer(serializers.Serializer):
username = serializers.CharField()
password = serializers.CharField(write_only=True)
def validate(self, data):
user = authenticate(**data)
if user and user.is_active:
return user
raise serializers.ValidationError("账号或密码错误")
2. 视图:业务逻辑的“咖啡师”
视图就像咖啡师,处理用户请求并返回响应:
# users/views.py
from rest_framework import status, permissions
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.authtoken.models import Token
from .serializers import *
class RegisterView(APIView):
permission_classes = [permissions.AllowAny] # 允许任何人注册
def post(self, request):
serializer = UserRegistrationSerializer(data=request.data)
if serializer.is_valid():
user = serializer.save()
token = Token.objects.create(user=user) # 创建Token
return Response({
"user": serializer.data,
"token": token.key,
"message": "注册成功!记得保管好Token哦~"
}, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class LoginView(APIView):
permission_classes = [permissions.AllowAny]
def post(self, request):
serializer = UserLoginSerializer(data=request.data)
if serializer.is_valid():
user = serializer.validated_data
token, created = Token.objects.get_or_create(user=user)
return Response({
"token": token.key,
"user_id": user.id,
"vip_level": user.vip_level
})
return Response(serializer.errors, status=status.HTTP_401_UNAUTHORIZED)
class UserProfileView(APIView):
# 默认需要Token认证(见settings配置)
def get(self, request):
user = request.user
return Response({
"username": user.username,
"email": user.email,
"vip_level": user.vip_level
})
3. 路由:请求的“传送带”
在urls.py中配置API端点:
# auth_api/urls.py
from django.urls import path, include
urlpatterns = [
path('api/auth/', include('users.urls')),
]
# users/urls.py
from django.urls import path
from .views import *
urlpatterns = [
path('register/', RegisterView.as_view(), name='register'),
path('login/', LoginView.as_view(), name='login'),
path('profile/', UserProfileView.as_view(), name='profile'),
]
五、权限控制:设置“会员专区”
现在来实现“金卡会员才能访问VIP接口”的功能:
# users/permissions.py
from rest_framework import permissions
class IsVipUser(permissions.BasePermission):
message = "仅限金卡会员访问!"
def has_permission(self, request, view):
return request.user.vip_level >= 2
# 在视图中使用
class VipContentView(APIView):
permission_classes = [permissions.IsAuthenticated, IsVipUser]
def get(self, request):
return Response({"content": "🔑 欢迎尊贵的金卡会员!这是专属限量版咖啡配方..."})
记得在urls.py中添加这个VIP接口的路径!
六、测试API:试试你的“咖啡机”
启动服务器:python manage.py runserver,然后用Postman或curl测试:
注册用户:
curl -X POST http://127.0.0.1:8000/api/auth/register/ \
-H "Content-Type: application/json" \
-d '{"username": "咖啡爱好者", "password": "test123", "vip_level": 2}'
登录获取Token:
curl -X POST http://127.0.0.1:8000/api/auth/login/ \
-H "Content-Type: application/json" \
-d '{"username": "咖啡爱好者", "password": "test123"}'
返回的Token像这样:{"token": "9944b09199c62b...", "user_id": 1}
访问需要权限的接口:
curl http://127.0.0.1:8000/api/auth/vip_content/ \
-H "Authorization: Token 9944b09199c62b..."
七、安全优化:给API加“防烫杯套”
- 密码加密:Django自动处理,但确保永远不明文存储!
- Token过期:默认Token永久有效,可通过
django-rest-framework-simplejwt实现JWT自动过期。 - 限流保护:在settings中添加:
REST_FRAMEWORK = {
...
'DEFAULT_THROTTLE_RATES': {
'login': '5/hour', # 登录限流
}
}
八、常见坑与填坑指南
- 循环导入:模型和序列化器互相引用时,使用字符串引用
'users.serializers.UserRegistrationSerializer' - 迁移失败:删除数据库文件并重新
migrate(仅开发环境!) - 权限不生效:检查
permission_classes是否被全局设置覆盖
结语:从API新手到“会员制大师”
恭喜!你现在已经搭建了一个完整的用户认证和权限系统。就像经营咖啡店,初期可能手忙脚乱,但熟悉后就能灵活定制各种“会员规则”。记住:好的API设计是用户体验的一半——就像一杯温度刚好的咖啡,让人回味无穷。
下一步,尝试为你的API添加邮箱验证、密码重置功能,或者探索Django Channels实现WebSocket认证。编程如冲咖啡,唯有不断实践才能掌握最佳风味。干杯!☕
Django用户认证与API实战
1159

被折叠的 条评论
为什么被折叠?



