Flask-Stripe Elements“ 400错误请求:CSRF令牌丢失或不正确”

时间:2019-03-10 01:52:36

标签: javascript python html flask stripe-payments

我正在遵循使用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>

2 个答案:

答案 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>

https://flask-wtf.readthedocs.io/en/stable/csrf.html