Context
我正在使用Django框架和Stripe在Python中构建一个网站,用于用户支付。我目前处于本地开发的测试/调试阶段,离生产构建还很远。
目前在用CSRF进行砖墙保护时,还找不到解决方案.我的结帐工作完美,没有CSRF保护。
这里还有其他非常类似的问题,但由于我缺乏CSRF保护本身的知识,我希望有人能启发我在我的特定情况下该怎么做。
这种情况应该有一个常见的实践解决方案,但我已经研究了Django和Stripe的大部分文档,没有运气。
欢迎批评,这是我的第一篇StackOverflow文章。
问题
我有一个视图功能,它可以通过将用户发送到Stripes外部结账页面来购买我网站上的产品。
views.py
@csrf_exempt # CSRF Protection disabled for testing
def create_checkout_session(request):
if request.method == 'POST':
try:
checkout_session = stripe.checkout.Session.create(
...
)
except Exception as e:
...
return redirect(checkout_session.url)
在测试期间,我使用Django的 @csrf_exempt 装饰器禁用了视图函数上的CSRF保护。我这样做是为了绕过'403 CSRF验证失败'错误。
我首先得到错误的原因是由于Django文档中的this statement:<form method="post">{% csrf_token %}
不应该对以外部URL为目标的POST表单执行此操作,因为这会导致CSRF令牌泄漏,从而导致漏洞。
在删除 @csrf_exempt 装饰器后,我现在卡住了,因为这正是我的提交表单的工作方式,如下面的 products.html 所示,结帐url是由stripe生成的(如www.example.com所示views.py),因此(我认为)是一个外部url:
products.html
<form rel="noreferrer" action="{% url 'checkout' %}" method="POST">
{% csrf_token %} <!-- forbidden in POST to external URL -->
<button rel="noreferrer" id="checkout-button" class="btn btn-sm" type="submit">
Buy
</button>
</form>
目前质疑以下几点:
- 有没有其他方法可以在不使用POST的情况下获得相同的结果?
- 我是否误解了Stripe文档?
- 结帐URL实际上是“外部”吗?
- 我是否应该放弃这种方法,并将Stripe的结帐硬编码到我的网站中以获得更好的安全性?
使用的资源:
- Stripe Documentation
- Django Documentation
- Windows 11
- PyCharm IDE
- Python 3.11
- Django 4.2
- 条纹5.4
- Firefox 114.0.1
我尝试过的:
我试图找到类似的解决方案,我发现这里有多个问题与我的问题有关,但没有一个我发现覆盖外部URL的CSRF保护的细节。
Django文档声明在POST到外部url时禁止使用{% csrf_token %},但经过进一步调查,没有详细说明任何解决方法或替代方案。
在得出解决方案并不明显的结论后,我的印象是,我的问题是由我自己引起的,因为我缺乏CSRF保护和Web安全方面的知识。这就把我带到了知识池StackOverflow。
2条答案
按热度按时间yvfmudvl1#
你实际上不需要使用csrf令牌,因为它是一个外部站点,有自己的安全性,我看不出不使用它会对你产生什么影响。Stripe有自己的保护机制,它会给予你一个webhook请求来确认一切正常,而不需要使用csrf令牌。
bxjv4tth2#
我假设你在
urls.py
中有这样的东西:所以当你在模板中有一个像这样的表单:
单击提交按钮将发布到您的视图。这意味着您应该保留CSRF令牌,不要使用
@csrf_exempt
装饰器。