我正在遵循使用Flask:https://stripe.com/docs/stripe-js/elements/quickstart的Stripe Elements的Stripe Quickstart指南,并且当令牌出现在Web控制台POST参数中时:
cardholder-name jane
stripeToken tok_1ECGDeCKSqZHGj511bnxBRad
POST尝试返回“ 400错误请求,CSRF令牌丢失或不正确。”
我的javascript与本教程一致,所以我认为可能与我的视图功能有关:
@billing.route('/charge', methods=['GET', 'POST'])
def charge():
token = request.form['stripeToken']
if request.method == 'POST':
customer = stripe.Customer.create(
email='customer@example.com',
source=token
)
"""
charge = stripe.Charge.create(
customer=customer.id,
amount=250,
currency='usd',
description='Flask Charge',
source=token
)
"""
return render_template('billing/charge.html', token=token
)
我一直在注释掉该函数的某些部分,以试图将问题隔离无济于事。将表格传递到服务器时是否犯了错误?或者,是否可以编写测试以调试400错误的测试?感谢所有代码的所有反馈。这是我的html表单代码供参考
<script src="https://js.stripe.com/v3/"></script>
<body>
<form role="form" action="{{ url_for('billing.charge') }}" method="post" id="payment-form">
<div class="group">
<label>
<span>Name</span>
<input name="cardholder-name" class="field" placeholder="Jane Doe" />
</label>
<label>
<span>Phone</span>
<input class="field" placeholder="(123) 456-7890" type="tel" />
</label>
</div>
<div class="group">
<label>
<span>Card</span>
<div id="card-element" class="field"></div>
</label>
</div>
<button type="submit">Pay $25</button>
<div class="outcome">
<div class="error"></div>
<div class="success">
Success! Your Stripe token is <span class="token"></span>
</div>
</div>
</form>
</body>
答案 0 :(得分:0)
我认为本教程(以及set-up-subscriptions示例代码)不会为CSRF所困扰,大概是为了简单起见。
Flask-WTF文档具有a bit about CSRF tokens,我认为它很有用。
我最终在我的Flask模板中放置了一个csrf_token
变量:
<script>
var csrf_token = {{ csrf_token()|tojson }};
</script>
然后在我的Stripe Elements代码中,调用/create-customer
时,我添加了一个额外的标头。这是set-up-subscriptions
存储库中的JavaScript函数,其中包含我的额外代码:
// Assumes that a global csrf_token variable has been set.
async function createCustomer(paymentMethod, cardholderEmail) {
return fetch('/create-customer', {
method: 'post',
headers: {
'X-CSRFToken': csrf_token, // This is the extra line
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: cardholderEmail,
payment_method: paymentMethod
})
})
.then(response => {
return response.json();
})
.then(subscription => {
handleSubscription(subscription);
});
}
我假设类似的方法可以与其他调用Flask后端的JS函数一起使用。
答案 1 :(得分:0)
您需要根据Flask文档向表单中添加CSRF令牌。
如果您使用的是FlaskForm
,请在表单中添加{{ form.csrf_token }}
。
<form method="post">
{{ form.csrf_token }}
</form>