如何基于Django+NGINX实现认证用户专属IP代理路由功能
实现基于Django+Nginx的认证式子域名代理服务
完全可以通过Django代码结合Nginx配置实现你的需求,核心是反向代理+子域名路由+用户认证的组合方案,不需要依赖复杂的VPN包。下面是具体实现步骤:
一、Django端核心实现
1. 子域名识别与路由映射
首先要让Django能识别子域名(比如XYZ.djangoproxy.com里的XYZ),可以自己写中间件提取子域名,核心逻辑是:
- 从请求的
Host头中提取子域名前缀 - 维护一个允许代理的第三方站点白名单(比如
ALLOWED_PROXY_DOMAINS = ["XYZ.com", "ABC.com"]),校验子域名对应的目标站点是否在列表内 - 将子域名映射到对应的目标站点,传递给代理视图
2. 登录认证校验
在代理视图上添加@login_required装饰器,确保只有已登录用户能使用代理功能。注意配置好Django的登录跳转逻辑,避免代理请求被拦截后出现异常跳转。
3. 反向代理视图代码
用requests库转发用户请求到第三方站点,同时处理请求头、响应头的适配,确保会话能在同一标签页保持:
from django.contrib.auth.decorators import login_required import requests from django.http import HttpResponse from django.conf import settings @login_required def proxy_view(request): # 提取子域名并匹配目标站点 host_parts = request.get_host().split('.') if len(host_parts) < 3: return HttpResponse("无效的代理域名", status=400) subdomain = host_parts[0] target_domain = f"{subdomain}.com" # 根据实际规则调整,比如从白名单映射 # 校验目标站点是否在允许列表内 if target_domain not in settings.ALLOWED_PROXY_DOMAINS: return HttpResponse("该站点不允许代理", status=403) # 构建目标URL target_url = f"https://{target_domain}{request.path}" # 转发请求头(排除Django特定头) headers = { k.replace('HTTP_', '').title().replace('_', '-'): v for k, v in request.META.items() if k.startswith('HTTP_') and k not in ['HTTP_HOST'] } headers['Host'] = target_domain # 转发请求 try: response = requests.request( method=request.method, url=target_url, headers=headers, data=request.POST, cookies=request.COOKIES, allow_redirects=False, timeout=10 ) except requests.exceptions.RequestException as e: return HttpResponse(f"代理请求失败: {str(e)}", status=502) # 处理响应,替换重定向地址为代理域名 django_response = HttpResponse(response.content, status=response.status_code) for key, value in response.headers.items(): if key.lower() == 'location': # 将第三方站点的重定向地址替换为代理子域名地址 value = value.replace(f"https://{target_domain}", f"https://{subdomain}.djangoproxy.com") django_response[key] = value return django_response
4. URL路由配置
在urls.py中添加路由,将所有子域名的请求指向代理视图:
from django.urls import path from .views import proxy_view urlpatterns = [ path('', proxy_view), path('<path:path>', proxy_view), # 匹配所有路径 ]
二、Nginx配置调整
1. 泛子域名监听
配置Nginx监听所有子域名,并转发请求到Django的WSGI服务:
server { listen 443 ssl; server_name *.djangoproxy.com djangoproxy.com; # SSL证书配置 ssl_certificate /path/to/your/cert.pem; ssl_certificate_key /path/to/your/key.pem; location / { proxy_pass http://127.0.0.1:8000; # Django服务地址 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 支持WebSocket(如果第三方站点需要) proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # 超时配置 proxy_connect_timeout 10s; proxy_send_timeout 10s; proxy_read_timeout 10s; } # 静态文件直接由Nginx处理 location /static/ { root /path/to/your/django/project; expires 30d; } }
2. 域名解析
确保域名服务商配置了泛解析记录(*.djangoproxy.com指向Nginx服务器的公网IP)。
三、关键注意事项
- IP白名单适配:Django服务必须部署在能访问第三方站点的网络环境中(比如办公区域内网,或通过公司公网IP出口访问),确保代理请求的源IP在第三方站点允许的IP段内。
- 安全防护:
- 严格限制允许代理的域名列表,避免被恶意滥用;
- 强制使用HTTPS传输,防止敏感数据泄露;
- 处理第三方站点的CSRF令牌传递,避免表单提交失败。
- 性能优化:可以用
aiohttp替代requests实现异步代理,提升并发能力;也可以在Nginx层面添加缓存规则,减少重复请求。
内容的提问来源于stack exchange,提问作者i'm PosSible
相关产品推荐
相关产品推荐

