Skip to content

Commit a3f599f

Browse files
committed
refactor: streamline admin authorization logic and improve token handling
1 parent 2e5dc53 commit a3f599f

File tree

2 files changed

+37
-52
lines changed

2 files changed

+37
-52
lines changed

apps/admin/dependencies.py

Lines changed: 33 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def verify_token(token: str) -> dict:
5050
).digest()
5151
expected_signature_b64 = base64.b64encode(expected_signature).decode()
5252

53-
if signature_b64 != expected_signature_b64:
53+
if not hmac.compare_digest(signature_b64, expected_signature_b64):
5454
raise ValueError("无效的签名")
5555

5656
# 解码payload
@@ -65,39 +65,41 @@ def verify_token(token: str) -> dict:
6565
raise ValueError(f"token验证失败: {str(e)}")
6666

6767

68+
def _extract_bearer_token(authorization: str) -> str:
69+
if not authorization or not authorization.startswith("Bearer "):
70+
raise HTTPException(status_code=401, detail="未授权或授权校验失败")
71+
token = authorization.split(" ", 1)[1].strip()
72+
if not token:
73+
raise HTTPException(status_code=401, detail="未授权或授权校验失败")
74+
return token
75+
76+
77+
def _require_admin_payload(authorization: str) -> dict:
78+
token = _extract_bearer_token(authorization)
79+
try:
80+
payload = verify_token(token)
81+
except ValueError as e:
82+
raise HTTPException(status_code=401, detail=str(e))
83+
if not payload.get("is_admin", False):
84+
raise HTTPException(status_code=401, detail="未授权或授权校验失败")
85+
return payload
86+
87+
88+
ADMIN_PUBLIC_ENDPOINTS = {("POST", "/admin/login")}
89+
90+
6891
async def admin_required(
6992
authorization: str = Header(default=None), request: Request = None
7093
):
7194
"""
7295
验证管理员权限
7396
"""
74-
try:
75-
if not authorization or not authorization.startswith("Bearer "):
76-
is_admin = False
77-
else:
78-
try:
79-
token = authorization.split(" ")[1]
80-
payload = verify_token(token)
81-
is_admin = payload.get("is_admin", False)
82-
except ValueError as e:
83-
is_admin = False
84-
85-
if request.url.path.startswith("/share/"):
86-
if not settings.openUpload and not is_admin:
87-
raise HTTPException(
88-
status_code=403, detail="本站未开启游客上传,如需上传请先登录后台"
89-
)
90-
else:
91-
if not is_admin:
92-
raise HTTPException(status_code=401, detail="未授权或授权校验失败")
93-
return is_admin
94-
except ValueError as e:
95-
raise HTTPException(status_code=401, detail=str(e))
97+
if request and (request.method, request.url.path) in ADMIN_PUBLIC_ENDPOINTS:
98+
return None
99+
return _require_admin_payload(authorization)
96100

97101

98-
async def share_required_login(
99-
authorization: str = Header(default=None), request: Request = None
100-
):
102+
async def share_required_login(authorization: str = Header(default=None)):
101103
"""
102104
验证分享上传权限
103105
@@ -109,21 +111,11 @@ async def share_required_login(
109111
:return: 验证结果
110112
"""
111113
if not settings.openUpload:
112-
try:
113-
if not authorization or not authorization.startswith("Bearer "):
114-
raise HTTPException(
115-
status_code=403, detail="本站未开启游客上传,如需上传请先登录后台"
116-
)
117-
118-
token = authorization.split(" ")[1]
119-
try:
120-
payload = verify_token(token)
121-
if not payload.get("is_admin", False):
122-
raise HTTPException(status_code=401, detail="未授权或授权校验失败")
123-
except ValueError as e:
124-
raise HTTPException(status_code=401, detail=str(e))
125-
except Exception as e:
126-
raise HTTPException(status_code=401, detail="认证失败:" + str(e))
114+
if not authorization or not authorization.startswith("Bearer "):
115+
raise HTTPException(
116+
status_code=403, detail="本站未开启游客上传,如需上传请先登录后台"
117+
)
118+
_require_admin_payload(authorization)
127119

128120
return True
129121

apps/admin/views.py

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
from core.settings import settings
2020
from core.utils import get_now, verify_password
2121

22-
admin_api = APIRouter(prefix="/admin", tags=["管理"])
22+
admin_api = APIRouter(
23+
prefix="/admin", tags=["管理"], dependencies=[Depends(admin_required)]
24+
)
2325

2426

2527
@admin_api.post("/login")
@@ -32,7 +34,7 @@ async def login(data: LoginData):
3234

3335

3436
@admin_api.get("/dashboard")
35-
async def dashboard(admin: bool = Depends(admin_required)):
37+
async def dashboard():
3638
all_codes = await FileCodes.all()
3739
all_size = str(sum([code.size for code in all_codes]))
3840
sys_start = await KeyValue.filter(key="sys_start").first()
@@ -61,7 +63,6 @@ async def dashboard(admin: bool = Depends(admin_required)):
6163
async def file_delete(
6264
data: IDData,
6365
file_service: FileService = Depends(get_file_service),
64-
admin: bool = Depends(admin_required),
6566
):
6667
await file_service.delete_file(data.id)
6768
return APIResponse()
@@ -73,7 +74,6 @@ async def file_list(
7374
size: int = 10,
7475
keyword: str = "",
7576
file_service: FileService = Depends(get_file_service),
76-
admin: bool = Depends(admin_required),
7777
):
7878
files, total = await file_service.list_files(page, size, keyword)
7979
return APIResponse(
@@ -89,7 +89,6 @@ async def file_list(
8989
@admin_api.get("/config/get")
9090
async def get_config(
9191
config_service: ConfigService = Depends(get_config_service),
92-
admin: bool = Depends(admin_required),
9392
):
9493
return APIResponse(detail=config_service.get_config())
9594

@@ -98,7 +97,6 @@ async def get_config(
9897
async def update_config(
9998
data: dict,
10099
config_service: ConfigService = Depends(get_config_service),
101-
admin: bool = Depends(admin_required),
102100
):
103101
data.pop("themesChoices")
104102
await config_service.update_config(data)
@@ -109,7 +107,6 @@ async def update_config(
109107
async def file_download(
110108
id: int,
111109
file_service: FileService = Depends(get_file_service),
112-
admin: bool = Depends(admin_required),
113110
):
114111
file_content = await file_service.download_file(id)
115112
return file_content
@@ -118,7 +115,6 @@ async def file_download(
118115
@admin_api.get("/local/lists")
119116
async def get_local_lists(
120117
local_file_service: LocalFileService = Depends(get_local_file_service),
121-
admin: bool = Depends(admin_required),
122118
):
123119
files = await local_file_service.list_files()
124120
return APIResponse(detail=files)
@@ -128,7 +124,6 @@ async def get_local_lists(
128124
async def delete_local_file(
129125
item: DeleteItem,
130126
local_file_service: LocalFileService = Depends(get_local_file_service),
131-
admin: bool = Depends(admin_required),
132127
):
133128
result = await local_file_service.delete_file(item.filename)
134129
return APIResponse(detail=result)
@@ -138,7 +133,6 @@ async def delete_local_file(
138133
async def share_local_file(
139134
item: ShareItem,
140135
file_service: FileService = Depends(get_file_service),
141-
admin: bool = Depends(admin_required),
142136
):
143137
share_info = await file_service.share_local_file(item)
144138
return APIResponse(detail=share_info)
@@ -147,7 +141,6 @@ async def share_local_file(
147141
@admin_api.patch("/file/update")
148142
async def update_file(
149143
data: UpdateFileData,
150-
admin: bool = Depends(admin_required),
151144
):
152145
file_code = await FileCodes.filter(id=data.id).first()
153146
if not file_code:

0 commit comments

Comments
 (0)