如何限制DRF邮件提交API仅接受自有网站表单的请求?
限制DRF邮件API仅接受自有网站请求的几种方案
针对你的需求,这里有几个实用的方法来限制API的访问来源,确保只有你自有网站的表单能调用这个邮件接口:
1. 检查HTTP Referer请求头
浏览器提交表单时会自动带上Referer头,记录请求发起的页面地址。我们可以在视图里验证这个头是否属于你的域名:
修改你的send_email函数,在处理POST请求前加入Referer校验:
from rest_framework import status from rest_framework.response import Response from rest_framework.decorators import api_view from django.conf import settings from django.core.mail import send_mail @api_view(['POST']) def send_email(request): # 新增:校验Referer头 ALLOWED_DOMAINS = ['https://yourdomain.com', 'https://www.yourdomain.com'] # 替换成你的实际域名 referer = request.META.get('HTTP_REFERER') if not referer: return Response({"error": "请求来源无效"}, status=status.HTTP_403_FORBIDDEN) # 检查Referer是否以允许的域名开头 is_allowed = any(referer.startswith(domain) for domain in ALLOWED_DOMAINS) if not is_allowed: return Response({"error": "拒绝访问"}, status=status.HTTP_403_FORBIDDEN) # 原有业务代码 if request.method == 'POST': name = request.data.get("name") email = request.data.get("email") subject = request.data.get("subject") message = request.data.get('message') message_con = 'Message: ' + message + '\nEmail: ' + email + '\nName of the sender: ' + name print("sent via POST") try: send_mail(subject, message_con, settings.EMAIL_HOST_USER, ['someemail@gmail.com']) return Response({"message": _("Email Successfully sent!")}) except Exception as e: print(e) return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) return Response({"error": _("Method Not Allowed.")}, status=status.HTTP_405_METHOD_NOT_ALLOWED)
提示:Referer头存在被伪造的可能,但对于普通恶意请求已足够,适合快速实现基础访问限制。
2. 启用CSRF保护
DRF默认对函数视图关闭了CSRF验证,但你的场景是自有网站的浏览器表单提交,可以开启CSRF保护,只有带正确CSRF令牌的请求才能通过:
步骤1:给视图添加CSRF保护装饰器
from django.views.decorators.csrf import csrf_protect from rest_framework.decorators import api_view @api_view(['POST']) @csrf_protect # 新增该装饰器启用CSRF验证 def send_email(request): # 原有业务代码不变
步骤2:前端表单中加入CSRF令牌
在你的HTML表单里添加Django的CSRF令牌模板标签,确保提交时带上令牌:
<form method="post" action="/path/to/send_email/"> {% csrf_token %} <!-- 其他表单字段:name、email、subject、message --> <button type="submit">发送邮件</button> </form>
这种方法是浏览器原生的安全机制,能有效防止跨站请求伪造,完全适配自有网站的表单场景。
3. 配置CORS策略(针对单页应用场景)
如果你的前端是React/Vue这类单页应用,通过AJAX提交请求,可以用django-cors-headers库限制允许访问API的域名:
步骤1:安装依赖
pip install django-cors-headers
步骤2:配置Django settings
# settings.py INSTALLED_APPS = [ # ... 其他已安装应用 'corsheaders', ] MIDDLEWARE = [ # 放在CommonMiddleware之前 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', # ... 其他中间件 ] # 仅允许你的域名访问API CORS_ALLOWED_ORIGINS = [ "https://yourdomain.com", "https://www.yourdomain.com", ]
提示:CORS是浏览器层面的限制,服务器端仍可能被直接调用,建议结合Referer校验或CSRF保护一起使用,提升整体安全性。
内容的提问来源于stack exchange,提问作者skagamer543
相关产品推荐
相关产品推荐

