51 lines
1.4 KiB
Python
51 lines
1.4 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""
|
||
认证 API:登录(无需 token)。
|
||
"""
|
||
import uuid
|
||
|
||
from rest_framework import status
|
||
from rest_framework.decorators import api_view, 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"])
|
||
@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
|