# -*- coding: utf-8 -*- """ 认证 API:登录(无需 token)。 """ import uuid from rest_framework import status from rest_framework.decorators import api_view, authentication_classes, permission_classes from rest_framework.permissions import AllowAny from rest_framework.response import Response from server import config from server.models import AuthToken from server.serializers import LoginSerializer @api_view(["POST"]) @authentication_classes([]) # 登录接口不校验 Cookie token,避免未带 Cookie 时被默认权限判为 403 @permission_classes([AllowAny]) def login(request): """ 登录接口(支持 JSON 和 form-data): - 校验用户名/密码 - 生成 token,写入数据库 - 通过 Set-Cookie 返回 auth_token,前端后续请求自动携带 - 下一次登录会生成新 token,旧 token 自动失效 """ ser = LoginSerializer(data=request.data) ser.is_valid(raise_exception=True) username = ser.validated_data["username"] password = ser.validated_data["password"] if username != config.ADMIN_USERNAME or password != config.ADMIN_PASSWORD: return Response({"detail": "用户名或密码错误"}, status=status.HTTP_401_UNAUTHORIZED) token = uuid.uuid4().hex AuthToken.objects.update_or_create( username=username, defaults={"token": token}, ) resp = Response({"token": token}) resp.set_cookie( key="auth_token", value=token, httponly=True, max_age=365 * 24 * 60 * 60, samesite="Lax", ) return resp