38 lines
1.1 KiB
Python
38 lines
1.1 KiB
Python
from typing import Union
|
|
from datetime import datetime, timedelta
|
|
|
|
from fastapi import Header, HTTPException, Request
|
|
|
|
import settings
|
|
|
|
|
|
async def admin_required(pwd: Union[str, None] = Header(default=None)):
|
|
if not pwd or pwd != settings.ADMIN_PASSWORD:
|
|
raise HTTPException(status_code=401, detail="密码错误")
|
|
|
|
|
|
class IPRateLimit:
|
|
ips = {}
|
|
|
|
def check_ip(self, ip):
|
|
# 检查ip是否被禁止
|
|
if ip in self.ips:
|
|
if self.ips[ip]['count'] >= settings.ERROR_COUNT:
|
|
if self.ips[ip]['time'] + timedelta(minutes=settings.ERROR_MINUTE) > datetime.now():
|
|
return False
|
|
else:
|
|
self.ips.pop(ip)
|
|
return True
|
|
|
|
def add_ip(cls, ip):
|
|
ip_info = cls.ips.get(ip, {'count': 0, 'time': datetime.now()})
|
|
ip_info['count'] += 1
|
|
cls.ips[ip] = ip_info
|
|
return ip_info['count']
|
|
|
|
def __call__(self, request: Request):
|
|
ip = request.client.host
|
|
if not self.check_ip(ip):
|
|
raise HTTPException(status_code=400, detail="错误次数过多,请稍后再试")
|
|
return ip
|