如何限制Django指定端点仅允许本地网络特定服务访问
实现Django接口细粒度访问限制方案
1. 直接判断请求来源方案的可靠性说明
你当前写的仅校验request.get_host()的方案不可靠,该字段取的是请求头的Host值,可被攻击者伪造。
如果微服务和Django部署在同一台服务器,优先校验请求来源IP更稳妥:request.META['REMOTE_ADDR']取的是TCP连接的对端IP,无法伪造,本地调用的话该值固定为127.0.0.1或者IPv6的::1,再配合Origin头校验就能实现非常可靠的访问限制。
2. 自定义局部访问限制装饰器实现
你要的其实不是「局部CORS」,而是接口级的访问权限控制:因为服务端发起的调用(比如FastAPI微服务请求Django接口)本身不受CORS规则约束,CORS只是限制浏览器跨域请求。直接写权限装饰器比折腾CORS配置更直接高效,实现代码如下:
from functools import wraps from django.http import Http404 from django.conf import settings def local_cors(allowed_origins): def decorator(view_func): @wraps(view_func) def _wrapped_view(request, *args, **kwargs): # 第一步:校验是不是本地回环访问,直接拦截所有外网请求 remote_ip = request.META.get('REMOTE_ADDR', '') if remote_ip not in ['127.0.0.1', '::1']: raise Http404 # 返回404隐藏接口存在,避免被扫描 # 第二步:可选校验Origin,确认是指定微服务发起的请求 origin = request.META.get('HTTP_ORIGIN', '') if origin not in allowed_origins: raise Http404 return view_func(request, *args, **kwargs) return _wrapped_view return decorator
使用方式和你预期的完全一致:
@local_cors(["http://localhost:9877"]) @decorators.action(detail=False, methods=["post"]) def get_data(self, request): return response.Response(status=200)
如果你的微服务HTTP客户端默认不携带Origin头,可以直接去掉Origin校验步骤,仅保留本地IP校验就足够安全。
3. CORS信号方案的适配方式
check_request_enabled信号可以用,作用是拦截前端浏览器跨域访问受限接口,和上面的权限装饰器搭配形成双重保障,调整后代码如下:
# myapp/handlers.py from corsheaders.signals import check_request_enabled def cors_allow_public_urls(sender, request, **kwargs): # 受限路径列表,换成你自己的接口路径 restricted_paths = ["/api/get-file-path/"] for path in restricted_paths: if request.path.startswith(path): # 受限路径不应用全局CORS配置,浏览器跨域请求直接被拦截 return False # 其余路径走全局CORS白名单配置,正常对前端开放 return True check_request_enabled.connect(cors_allow_public_urls)
内容的提问来源于stack exchange,提问作者tugot17
相关产品推荐
相关产品推荐

