部署在AWS App Runner的Django无法发邮件及CSRF问题求助
Django在AWS App Runner发送邮件时出现502/源检查失败问题排查
问题描述
我在AWS App Runner上运行的Django应用发送邮件时,页面长时间加载后变为空白,调试工具显示502错误:源检查失败,{我的域名}与任何可信源都不匹配。
添加CSRF_TRUSTED_ORIGINS、CORS_ORIGIN_WHITELIST、CORS_ALLOWED_ORIGINS、SECURE_PROXY_SSL_HEADER这些配置项后,错误变为:源检查失败 - null与任何可信源都不匹配。
HTML中已包含{% csrf_token %}标签,注释掉send_email函数后一切正常,说明问题出在邮件发送环节。SES的发件人和收件人身份已验证,依赖已安装,邮件相关配置如下:
EMAIL_BACKEND = 'django_ses.SESBackend' AWS_SES_REGION_NAME = 'us-east-2' AWS_SES_REGION_ENDPOINT = 'email.us-east-2.amazonaws.com'
访问密钥已配置,本地通过python manage.py runserver可正常发送邮件,安全组已允许所有进出流量。
相关视图函数代码
def nuevaorden_view(request): if request.method == "POST": try: nombre = request.POST.get("nombre") email = request.POST.get("email") telefono = request.POST.get("telefono") TipoDeServicio = request.POST.get("TipoDeServicio") ServiciosCombinados = request.POST.getlist("ServiciosCombinados") FrecuenciaDeServicio = request.POST.get("FrecuenciaDeServicio") Description = request.POST.get("Description") CiudadOrigen = request.POST.get("CiudadOrigen") PaisOrigen = request.POST.get("PaisOrigen") CodigoPostalOrigen = request.POST.get("CodigoPostalOrigen") CiudadDestino = request.POST.get("CiudadDestino") PaisDestino = request.POST.get("PaisDestino") CodigoPostalDestino = request.POST.get("CodigoPostalDestino") Status = 'Orden Abierta' Carrier = 'CorreKaminos' orden = NuevaOrden( nombre=nombre, email=email, telefono=telefono, TipoDeServicio=TipoDeServicio, ServiciosCombinados=ServiciosCombinados, FrecuenciaDeServicio=FrecuenciaDeServicio, Description=Description, CiudadOrigen=CiudadOrigen, PaisOrigen=PaisOrigen, CodigoPostalOrigen=CodigoPostalOrigen, CiudadDestino=CiudadDestino, PaisDestino=PaisDestino, CodigoPostalDestino=CodigoPostalDestino, Status=Status, Carrier=Carrier ) try: orden.save() except Exception as e: print(e) try: mail_subject = "Nueva orden" message = ('Una nueva orden ha sido creada.') from_email = "IvanGonzalez@correkaminos.com" to_email = ['carlosugartechea@correkaminos.com'] send_mail(mail_subject, message, from_email, to_email, fail_silently=False) messages.success(request, "La orden se ha creado correctamente.") return render(request, "ordenes/ordenregistrada.html") except Exception as e: print(e) return render(request, "ordenes/nuevaorden.html") except Exception as e: print(e) return render(request, "ordenes/nuevaorden.html")
可行的排查解决方法
- 检查App Runner环境变量:确保
AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY正确配置在App Runner的环境变量中,不要硬编码在代码里。本地能运行是因为本地有凭证,但App Runner需要明确配置这些变量。 - 修正CSRF_TRUSTED_ORIGINS格式:必须包含完整协议(http/https)和域名,比如
https://your-app-runner-domain.awsapprunner.com,自定义域名也要按此格式添加,不能只写域名。 - 验证SES权限:确认App Runner使用的IAM角色(或访问密钥)拥有
ses:SendEmail和ses:SendRawEmail权限,权限范围需覆盖us-east-2区域。 - 延长请求超时时间:邮件发送可能耗时较长,App Runner默认请求超时可能不足导致502错误,可在服务配置中将超时时间延长至最大180秒。
- 查看App Runner应用日志:不要只依赖前端错误信息,去App Runner日志页面查看应用的具体报错,比如SES连接失败、权限错误等,这些日志能直接定位问题根源。
- 测试极简邮件发送用例:写一个只包含邮件发送逻辑的测试接口,排除表单保存等其他逻辑干扰,单独验证邮件发送是否正常,缩小问题范围。
- 确认SECURE_PROXY_SSL_HEADER配置:如果App Runner使用HTTPS,确保配置正确:
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https'),生产环境同步设置SECURE_SSL_REDIRECT = True,保证Django识别正确的请求协议。 - 核对CORS配置:若使用django-cors-headers,确保
CORS_ALLOWED_ORIGINS包含App Runner域名和自定义域名,格式为https://your-domain.com,不要遗漏协议部分。
内容的提问来源于stack exchange,提问作者IvanGonzalez
相关产品推荐
相关产品推荐

