This commit is contained in:
ddrwode
2026-02-25 19:10:13 +08:00
parent a315e5f2e1
commit 42b68ededd
6 changed files with 19 additions and 36 deletions

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
"""
认证 API登录无需 token
认证 API登录无需 Authorization
"""
import uuid
@@ -15,14 +15,14 @@ from server.serializers import LoginSerializer
@api_view(["POST"])
@authentication_classes([]) # 登录接口不校验 Cookie token避免未带 Cookie 时被默认权限判为 403
@authentication_classes([]) # 登录接口不校验 Authorization
@permission_classes([AllowAny])
def login(request):
"""
登录接口(支持 JSON 和 form-data
- 校验用户名/密码
- 生成 token写入数据库
- 通过 Set-Cookie 返回 auth_token前端后续请求自动携带
- 返回 token前端可放到 Authorization 请求头)
- 下一次登录会生成新 token旧 token 自动失效
"""
ser = LoginSerializer(data=request.data)
@@ -40,12 +40,4 @@ def login(request):
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
return Response({"token": token})

View File

@@ -1,9 +1,8 @@
# -*- coding: utf-8 -*-
"""
DRF 自定义认证后端:从 Cookie 中读取 auth_token 校验
DRF 自定义认证后端:只要请求头包含 Authorization 即视为已认证
"""
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
class TokenUser:
@@ -17,22 +16,17 @@ class TokenUser:
return self.username
class CookieTokenAuthentication(BaseAuthentication):
"""
从请求 Cookie 中读取 auth_token查数据库校验。
"""
class HeaderAuthorizationAuthentication(BaseAuthentication):
"""仅要求请求头中存在 Authorization 字段。"""
def authenticate(self, request):
token = request.COOKIES.get("auth_token")
if not token:
return None # 未携带 token交给权限类处理
if "HTTP_AUTHORIZATION" not in request.META:
return None # 未携带 Authorization交给权限类处理
# 延迟导入避免循环依赖
from server.models import AuthToken
# 只要求字段存在,不校验值内容。
auth_value = request.headers.get("Authorization", "")
return (TokenUser("authorization_header_user"), auth_value)
try:
row = AuthToken.objects.get(token=token)
except AuthToken.DoesNotExist:
raise AuthenticationFailed("登录已失效,请重新登录")
return (TokenUser(row.username), token)
# 兼容旧配置名
CookieTokenAuthentication = HeaderAuthorizationAuthentication

View File

@@ -52,7 +52,7 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
# ─── DRF ───
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [
"server.core.authentication.CookieTokenAuthentication",
"server.core.authentication.HeaderAuthorizationAuthentication",
],
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework.permissions.IsAuthenticated",

BIN
下载 (1).png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

BIN
下载.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -1,20 +1,17 @@
import requests
url = "http://8.137.99.82:9000/api/auth/login"
url = "http://8.137.99.82:9000/api/accounts"
payload={}
files=[
]
headers = {
# 'Authorization': '082af0d858ea4d23a905c82bab753d15',
'User-Agent': 'Apifox/1.0.0 (https://apifox.com)',
'Accept': '*/*',
'Host': '8.137.99.82:9000',
'Connection': 'keep-alive',
'Content-Type': 'multipart/form-data; boundary=--------------------------967987379917827495982839',
'Cookie': 'auth_token=c0ceff1a701e49538965813027f80edb'
'Cookie': 'auth_token=082af0d858ea4d23a905c82bab753d15'
}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)