React集成Stripe支付遇认证错误:已配置Bearer Header仍失效
问题分析与解决方案
核心错误原因
你犯了两个关键错误:
- 绝对不能把Stripe Secret Key放在前端代码里:这是严重的安全漏洞,任何人都能从前端代码中获取你的Secret Key,进而操作你的Stripe账户。
- 后端没有正确初始化Stripe客户端:后端调用Stripe API时未传入Secret Key,这才是导致
StripeAuthenticationError的根本原因——和你前端添加的Authorization头完全无关。
分步解决
1. 修复前端代码(移除Secret Key,清理无效逻辑)
前端仅需使用Stripe的Publishable Key,无需传递Secret Key给后端。删除axios拦截器中的Authorization头配置,确保Stripe用Publishable Key初始化:
function PaymentForm ({formData, setFormData, setIsLoading}) { const stripe = useStripe() const elements = useElements() // 移除带Secret Key的拦截器配置 const API = axios.create({baseURL:'http://localhost:3500'}); const handleSubmit = async (e) => { e.preventDefault() const {error, paymentMethod} = await stripe.createPaymentMethod({ type: "card", card: elements.getElement(CardElement) }) if(!error) { try { setIsLoading(true) const {id} = paymentMethod // 仅传递支付必要参数,不要传Secret Key const response = await API.post("/payment", { amount: 1000, id, description:'Advertising Purchase' }) if(response.data.success) { console.log("Successful payment") setFormData({...formData, paid: true}) setIsLoading(false) } } catch (error) { setIsLoading(false) alert(error) } } else { console.log(error.message) } } return ( <> {!formData.paid ? <form onSubmit={handleSubmit} style={{marginTop:'2rem', textAlign:'center'}}> <fieldset className="FormGroup"> <div className="FormRow"> <CardElement options={CARD_OPTIONS}/> </div> </fieldset> <Button type='submit' variant='contained'>PAY ${Number(formData.price)/100 * 5}</Button> </form> : <div> <h2>You just bought a sweet spatula congrats this is the best decision of you're life</h2> </div> } </> ) }
另外,确保你的Stripe初始化代码(比如在App.js中)使用Publishable Key:
import { loadStripe } from '@stripe/stripe-js'; const stripePromise = loadStripe('pk_test_你的PublishableKey');
2. 修复后端代码(正确初始化Stripe客户端)
后端需要用你的Stripe Secret Key初始化Stripe SDK,之后再调用API。推荐用环境变量存储密钥,避免硬编码:
// 导入Stripe并初始化,替换为你的Secret Key const stripe = require('stripe')('sk_test_你的SecretKey'); // 更安全的方式:使用环境变量 // const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY); app.post("/payment", cors(), async (req, res) => { let { amount, id, description } = req.body try { const payment = await stripe.paymentIntents.create({ amount, currency: "USD", description: description, payment_method: id, confirm: true }) console.log("Payment", payment) res.json({ message: "Payment successful", success: true }) } catch (error) { console.log("Error", error) res.json({ message: "Payment failed", success: false }) } })
额外说明
- Stripe的认证逻辑:后端调用Stripe API时,必须通过初始化SDK传入Secret Key,或在请求头中携带
Authorization: Bearer sk_test_xxx,官方推荐使用初始化SDK的方式。 - 前端的Publishable Key仅用于初始化Stripe Elements,不能调用需要权限的API,所有敏感操作必须在后端完成。
内容的提问来源于stack exchange,提问作者Calin Onaca
相关产品推荐
相关产品推荐

