如何将 django 端点限制为本地网络?
Posted
技术标签:
【中文标题】如何将 django 端点限制为本地网络?【英文标题】:How to restrict django endpoint to localnetwork? 【发布时间】:2021-09-20 09:18:12 【问题描述】:在我的项目中,我使用许多 FastAPI 微服务来执行指定的任务,并使用 Django 应用程序来处理用户操作、连接前端等。 在 Django 数据库中,我存储有关微服务应获取的文件路径的信息。我只想将它提供给微服务和这个微服务。所以我想限制对端点的访问到本地网络上的指定端口。
其他端点通常应可用于 Web 应用程序。仅使用 Django cors 标头将不起作用,因为我希望正常访问大多数端点并将其限制为 localhost 仅用于一小部分子集。
CORS_ORIGIN_WHITELIST = [
"http://my_frontend_app" # most of the endpoints available from the front end
"http://localhost:9877", #the microservice that I want to provide with the path
]
另一种解决方案可能是使用from corsheaders.signals import check_request_enabled
,但在the use cases that I have seen 中,它通常用于扩大访问范围,而不是限制它(前端不应访问端点子集)。我不确定这是否是一个好的解决方案。
# myapp/handlers.py
from corsheaders.signals import check_request_enabled
def cors_allow_particular_urls(sender, request, **kwargs):
return request.path.startswith('/public-api/')
check_request_enabled.connect(cors_allow_mysites)
有什么方法可以创建“本地 cors”,例如,以装饰器的形式?它看起来像:
@local_cors([“localhost:9877”])
@decorators.action(detail=False, methods=["post"])
def get_data(self, request):
return response.Response(status=200)
localhost:9877
是微服务的地址
这样的解决方案是否足够好?
def get_data(self, request):
request_host = request.get_host()
data = request.data
if request_host != MAP_UPLOAD_HOST:
# we don't show the endpoint to the outside return
response.Response(status=404)
return response.Response(status=200)
【问题讨论】:
如果你真的只想允许一个调用者访问,CORS 是不够的:有人可以通过其他方式访问该视图(甚至可能不使用 Web 浏览器)。这有关系吗? 是的。 CORS 不足以限制访问? CORS 仅由 Web 浏览器强制执行,以防止将信息泄漏到可能请求它的不相关页面。您需要某种访问控制,方法是对调用者进行身份验证或限制对相关 URL 的访问。 所以我应该通过使用类似“if request.headers['Origin'] == "localhost:9877"? 【参考方案1】:使用get_host()
检查Host
标头可能提供足够的保护,具体取决于您的服务器设置。
get_host()
将告诉您请求中Host
标头的值,这是客户端提供的数据,因此可以以任何方式进行操作。 Host
标头是 HTTP 1.1 的一个组成部分,它允许多个域托管在一个地址上,因此您可以依靠您的服务器拒绝实际上不是来自 localhost
并带有匹配标头的请求,但很难确定。
check the client's network address 可能更可靠,并拒绝所有客户端的请求,特别允许的请求除外。
【讨论】:
以上是关于如何将 django 端点限制为本地网络?的主要内容,如果未能解决你的问题,请参考以下文章
如何将媒体文件的 URL 限制为 Django 中未经身份验证的用户?