根据@tarunlalwani提供的线索(万分感谢!)在他的评论中,我设法想出了一个解决办法。
Cookie域设置
因为我使用的是两个独立的站点,为了让这一点起作用,我必须确保它们都在同一个域上,并且该域设置在所有cookies中。这确保了cookies包含在节点/快速服务器之间的我的请求中(位于
somedomain.com
)和Woocommerce CMS(坐在
wp.somedomain.com
,而不是对
wp.somedomain
子域。这是通过设置
define( 'COOKIE_DOMAIN', 'somedomain.com' );
在我的
wp-config.php
在CMS上。
手动获取和设置Cookie
我的代码需要大量的额外逻辑,以便在请求通过我的节点/快速服务器通过客户端路由时包含cookie。
在反应中,我必须检查cookie是否存在,如果是这样的话,我必须在get请求的标题中把它发送给节点/ Express服务器。
import Cookies from 'js-cookie';
export const getSessionData = () => {
const cookies = Cookies.get();
if (cookies) {
const cookieKeys = Object.keys(cookies);
for (const key of cookieKeys) {
if (key.includes('wp_woocommerce_session_')) {
return `${key}=${Cookies.get(key)};`;
}
}
}
return false;
};
export const addToCart = (productId, quantity) => async (dispatch) => {
dispatch({type: ADD_TO_CART});
const sessionData = getSessionData();
const config = {};
if (sessionData) config['session-data'] = sessionData;
console.log('config', config);
try {
const payload = await axios.get(`${ROOT_API}/addtocart?productId=${productId}&quantity=${quantity}`, {
withCredentials: true,
headers: config
});
dispatch(addToSuccess(payload));
} catch (error) {
dispatch(addToCartFailure(error));
}
};
在node/express服务器上,我必须检查是否包含cookie(保存在
req.headers
带着钥匙
session-data
-使用是违法的
Cookie
作为这里的一个键),从客户端,如果我这样做了,附加到我的请求头到我的CMS。
如果我没有找到附加的cookie,这意味着这是会话中的第一个请求,因此我必须从cms返回的响应中手动获取cookie并将其保存到客户端(
setCookieFunc
)中。
app.get('/api/addtocart', async (req, res) => {
try {
const productId = parseInt(req.query.productId);
const quantity = parseInt(req.query.quantity);
const sessionData = req.headers['session-data'];
const headers = {};
if (sessionData) headers.Cookie = sessionData;
const response = await axios.post(`${WP_API}/wc/v2/cart/add`, {
product_id: productId,
quantity
}, { headers });
if (!sessionData) {
const cookies = response.headers['set-cookie'];
const setCookieFunc = (cookie) => {
const [cookieKeyValue, ...cookieOptionsArr] = cookie.split('; ');
const cookieKey = cookieKeyValue.split('=')[0];
const cookieValue = decodeURIComponent(cookieKeyValue.split('=')[1]);
const cookieOptions = { };
cookieOptionsArr.forEach(option => (cookieOptions[option.split('=')[0]] = option.split('=')[1]));
if (cookieOptions.expires) {
const expires = new Date(cookieOptions.expires);
cookieOptions.expires = expires;
}
res.cookie(cookieKey, cookieValue, cookieOptions);
};
cookies.map(cookie => setCookieFunc(cookie));
}
return res.json(response.data);
} catch (error) {
return res.json(error);
}
});
我不确定这是否是解决这个问题最优雅的方法,但它对我有效。
笔记
我用了
js-cookie
用于在我的react客户端上与cookies交互的库。
哥特恰
如果您试图在开发环境中(使用localhost)实现此功能,则需要做一些额外的工作。见
Cookies on localhost with explicit domain