Strapi集成Stripe支付网关遇401未授权问题求助
Next.js电商网站Strapi支付API 401未授权错误排查
问题背景
用Next.js搭建电商站点,采用Strapi作为CMS、Stripe作为支付网关。后端已编写支付操作API代码,但前端点击结账按钮调用该API时,出现401未授权错误,无法跳转到Stripe结账页面。
后端Strapi Order控制器代码
'use strict'; // @ts-ignore const stripe = require('stripe')(process.env.STIPE_SECRET_KEY); /** * order controller */ const { createCoreController } = require('@strapi/strapi').factories; module.exports = createCoreController('api::order.order', ({ strapi }) => ({ async create(ctx) { // @ts-ignore const { products } = ctx.request.body; const lineItems = await Promise.all( products.map(async (product) => { const item = await strapi .service("api::product.product") .findOne(product.id); return { price_data: { currency: "cad", product_data: { name: item.title, }, unit_amount: item.price * 100, }, quantity: item.quantity, }; }) ); try { const session = await stripe.checkout.sessions.create({ shipping_address_collection: { allowed_countries: ['US', 'CA'] }, payment_method_types: ["card"], mode: "payment", success_url:`${process.env.CLIENT_URL}?success=true`, cancel_url: `${process.env.CLIENT_URL}??success=false`, line_items: lineItems, }); await strapi.service("api::order.order").create({ data: { products, stripeId: session.id } }); return { stripeSession: session }; } catch (error) { ctx.response.status = 500; return { error }; } } }));
前端结账按钮处理函数
const stripePromise = loadStripe( "pk_test_51P2oOLKBSRV7dryrpTP3KRN4DZKqvqj7B9cgBPib65JdpIZa5g9i2QTP8VruvddPl5zG8dq7OAa4fIoUGG8f7Ido00hVKbRT1R" ); const handlePayment = async () => { try { const stripe = await stripePromise; const res = await makeRequest.post("/orders", { products: cartItemList, }); await stripe.redirectToCheckout({ sessionId: res.data.stripeSession.id, }); } catch (err) { console.log(err); } };
错误信息
AxiosError { message: 'Request failed with status code 401', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: { transitional: { silentJSONParsing: true, forcedJSONParsing: true, clarifyTimeoutError: false }, adapter: [ 'xhr', 'http' ], transformRequest: [ 0: λ:transformRequest ], transformResponse: [ 0: λ:transformResponse ], timeout: 0, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, env: {}, headers: AxiosHeaders { Accept: 'application/json, text/plain, */*', 'Content-Type': 'application/json', Authorization: 'bearer undefined' }, baseURL: 'http://localhost:1337/api', method: 'post', url: '/orders', data: '{"products":[{"name":"Masar Green One","quantity":3,"amount":270,"image":"/uploads/Rectangle_90_84c9813ece.png","actualPrice":100,"id":32,"product":1}]}' }, request: XMLHttpRequest { onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload { onloadstart: null, onprogress: null, onabort: null, onerror: null, onload: null, ontimeout: null, onloadend: null }, responseURL: 'http://localhost:1337/api/orders', status: 401, statusText: 'Unauthorized', responseType: '', response: '{"data":null,"error":{"status":401,"name":"UnauthorizedError","message":"Missing or invalid credentials","details":{}}}', responseText: '{"data":null,"error":{"status":401,"name":"UnauthorizedError","message":"Missing or invalid credentials","details":{}}}' }
解决方案
从错误信息可见,请求头的Authorization字段为bearer undefined,核心问题是前端请求未携带有效认证凭证,或Strapi接口权限未开放。
1. 开放Strapi接口权限
- 进入Strapi后台,打开
Content-Type Builder,找到Order集合 - 切换到
Permissions标签页,找到create权限,为Public角色开启该权限(无需用户登录即可结账场景) - 保存设置后重启Strapi服务
2. 修复前端认证凭证
若接口需要用户登录认证,确保makeRequest实例能正确获取并携带JWT token:
// 从本地存储或状态管理中获取用户token const token = localStorage.getItem('userToken'); // 配置axios实例 const makeRequest = axios.create({ baseURL: 'http://localhost:1337/api', headers: { Authorization: token ? `Bearer ${token}` : undefined } });
3. 排查路由中间件
检查自定义Order控制器是否添加了额外的认证拦截中间件,确认Strapi默认权限中间件配置正常。
4. 临时测试无认证请求
先临时关闭Order接口的认证权限,测试是否能成功创建Stripe会话,排除代码逻辑本身的问题。
内容的提问来源于stack exchange,提问作者Farijul Tanzil
相关产品推荐
相关产品推荐

