Teilen von Cookies zwischen Websites auf derselben Domain – Headless / Entkoppeltes CMS
Lesezeit: 6 Minuten
Allan aus Sydney
Der Kontext meiner Herausforderung
Ich baue einen Headless WordPress / WooCommerce Store.
Wenn Sie mit dem Konzept eines Headless-CMS nicht vertraut sind, ziehe ich den Inhalt des Shops (Produkte und ihre Bilder, Text) über die WordPress / WooCommerce-REST-API. Auf diese Weise habe ich den Vorteil eines CMS-Dashboards für meinen Kunden, während ich in einer modernen Sprache / Bibliothek entwickeln kann, in meinem Fall – React!
Wenn möglich möchte ich den Checkout in WordPress/WooCommerce/PHP beibehalten. Je nach Projekt, auf das ich diesen Code/Boilerplate anwende, vermute ich, dass ich Zahlungs-Gateways hacken und ändern muss, und dies sicher und PCI-konform zu machen, wird in PHP/WordPress viel einfacher sein – dafür gibt es eine ganze Reihe von Plugins.
Das bedeutet, dass der gesamte Shop / das gesamte Frontend in React leben wird, mit Ausnahme des Warenkorbs, in dem der Benutzer zum CMS-Frontend (WordPress, PHP) weitergeleitet wird, wenn er seine Bestellung abschließen möchte.
Die Herausforderung
Dies macht die Verwaltung von Cookies für die Sitzung ziemlich unintuitiv und unorthodox. Wenn der Benutzer vom Geschäft (React-Site) zur Kasse (WooCommerce/PHP-Site) umgeleitet wird, muss die Warenkorbsitzung zwischen den beiden Sites bestehen bleiben.
Außerdem werden Anfragen an WooCommerce über den Node/Express-Server geleitet, auf dem mein React-Client sitzt. Ich mache das, weil ich die WordPress-Adresse verschleiert halten möchte, und so kann ich GraphQL anwenden, um meine Anfragen und Antworten zu bereinigen. Dieses Problem besteht darin, dass bei diesem Prozess die Cookies verloren gehen, weil mein Client und mein CMS über einen Mittelsmann (meinen Node-Server) kommunizieren – ich benötige zusätzliche Logik, um meine Cookies manuell zu verwalten.
Der Code
Wenn ich versuche, etwas zu einem Warenkorb hinzuzufügen, treffe ich von einem Aktionsersteller (ich verwende Redux für die Zustandsverwaltung) auf den entsprechenden API-Endpunkt auf meinem Node/Express-Server:
Hast du es mit der Einstellung versucht define( 'COOKIE_DOMAIN', 'somedomain.com' ); in deiner wp-config.phpstellt dies sicher, dass WordPress Cookies in der Hauptdomäne und nicht in der Unterdomäne generiert, und beide teilen die Cookies mit allem Extra, also keine Codekomplexität wie Sie sie derzeit haben
– Tarun Lalwani
15. Juli 2018 um 17:21 Uhr
Danke für den Tipp @TarunLalwani – ich habe es nicht ausprobiert, ich werde es versuchen! Es wäre erstaunlich, wenn dies alle meine Keksprobleme lösen könnte. Mein anfängliches Zögern wäre das EIN) Ob WooCommerce diese Option berücksichtigt oder nicht, und B) Dass alle REST-API-Aufrufe von React an WordPress serverseitig (node, express) und nicht clientseitig (react) erfolgen. Ich stelle mir vor, dass dies die Fähigkeit von Axios (meinem HTTP-Client) beeinträchtigen würde, den Anfragen, die ich an WordPress sende, automatisch relevante Browser-Cookies hinzuzufügen
– Allan aus Sydney
15. Juli 2018 um 21:36 Uhr
A) Kann ausgeräumt werden – Ich habe eine Bestätigung von den Devs gefunden, dass: “WooCommerce verwendet die gleichen Cookie-Einstellungen wie WordPress (z. B. WordPress-Login-Cookie)”
– Allan aus Sydney
15. Juli 2018 um 22:10 Uhr
Für B müssen Sie alle Browser-Cookies in Ihrer Anfrage an WP senden und dasselbe auch für Rückgabe-Cookies tun
– Tarun Lalwani
16. Juli 2018 um 2:46 Uhr
Sie haben Recht, ich muss meine Cookies vom Client (React) an den Server (Node) weitergeben, bevor ich auf das CMS (WooCommerce über REST) treffe, und dann ähnlich umgekehrt, indem ich Cookies für den Client innerhalb des Knotens setze Server. Es ist kompliziert, aber es ist fast geschafft!
– Allan aus Sydney
16. Juli 2018 um 10:18 Uhr
Allan aus Sydney
Mit den Hinweisen von @TarunLalwani (tausend Dank!) in seinen Kommentaren ist es mir gelungen, eine Lösung zu formulieren.
Cookie-Domain-Einstellung
Da ich mit zwei separaten Websites arbeitete, musste ich sicherstellen, dass sich beide auf derselben Domäne befanden und dass die Domäne in allen Cookies festgelegt war, damit dies funktionierte. Dadurch wurde sichergestellt, dass Cookies in meine Anfragen zwischen dem Node / Express-Server (sitzen auf z. somedomain.com) und das WooCommerce CMS (sitzt auf zB. wp.somedomain.com), anstatt exklusiv für die wp.somedomain Unterdomäne. Dies wurde durch Einstellung erreicht define( 'COOKIE_DOMAIN', 'somedomain.com' ); in meinem wp-config.php auf dem CMS.
Manuelles Abrufen und Setzen von Cookies
Mein Code benötigte eine erhebliche zusätzliche Logik, damit Cookies eingeschlossen werden konnten, während Anfragen über meinen Node/Express-Server durch den Client geleitet wurden.
In React musste ich überprüfen, ob das Cookie existierte, und wenn ja, musste ich es im Header meiner GET-Anfrage an den Node / Express-Server senden.
import Cookies from 'js-cookie';
export const getSessionData = () => {
// WooCommerce session cookies are appended with a random hash.
// Here I am tracking down the key of the session cookie.
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));
}
};
Auf dem Node/Express Server musste ich prüfen, ob ich ein Cookie eingebunden hatte (gespeichert in req.headers mit dem Schlüssel session-data – Die Verwendung war illegal Cookie als Schlüssel hier) vom Client, und wenn ja, hängen Sie das an den Header meiner Anfrage an, die an mein CMS geht.
Wenn ich kein angehängtes Cookie fand, bedeutete dies, dass dies die erste Anfrage in der Sitzung war, also musste ich das Cookie manuell aus der Antwort holen, die ich vom CMS zurückbekam, und es auf dem Client speichern (setCookieFunc).
Ich bin mir nicht sicher, ob dies die eleganteste Lösung für das Problem ist, aber es hat für mich funktioniert.
Anmerkungen
Ich habe die verwendet js-Cookie Bibliothek für die Interaktion mit Cookies auf meinem React-Client.
Fallstricke
Wenn Sie versuchen, dies in Ihrer Entwicklungsumgebung (unter Verwendung von localhost) zum Laufen zu bringen, müssen Sie zusätzliche Arbeit leisten. Siehe Cookies auf Localhost mit expliziter Domäne
13867400cookie-checkTeilen von Cookies zwischen Websites auf derselben Domain – Headless / Entkoppeltes CMSyes
Hast du es mit der Einstellung versucht
define( 'COOKIE_DOMAIN', 'somedomain.com' );
in deinerwp-config.php
stellt dies sicher, dass WordPress Cookies in der Hauptdomäne und nicht in der Unterdomäne generiert, und beide teilen die Cookies mit allem Extra, also keine Codekomplexität wie Sie sie derzeit haben– Tarun Lalwani
15. Juli 2018 um 17:21 Uhr
Danke für den Tipp @TarunLalwani – ich habe es nicht ausprobiert, ich werde es versuchen! Es wäre erstaunlich, wenn dies alle meine Keksprobleme lösen könnte. Mein anfängliches Zögern wäre das EIN) Ob WooCommerce diese Option berücksichtigt oder nicht, und B) Dass alle REST-API-Aufrufe von React an WordPress serverseitig (node, express) und nicht clientseitig (react) erfolgen. Ich stelle mir vor, dass dies die Fähigkeit von Axios (meinem HTTP-Client) beeinträchtigen würde, den Anfragen, die ich an WordPress sende, automatisch relevante Browser-Cookies hinzuzufügen
– Allan aus Sydney
15. Juli 2018 um 21:36 Uhr
A) Kann ausgeräumt werden – Ich habe eine Bestätigung von den Devs gefunden, dass: “WooCommerce verwendet die gleichen Cookie-Einstellungen wie WordPress (z. B. WordPress-Login-Cookie)”
– Allan aus Sydney
15. Juli 2018 um 22:10 Uhr
Für B müssen Sie alle Browser-Cookies in Ihrer Anfrage an WP senden und dasselbe auch für Rückgabe-Cookies tun
– Tarun Lalwani
16. Juli 2018 um 2:46 Uhr
Sie haben Recht, ich muss meine Cookies vom Client (React) an den Server (Node) weitergeben, bevor ich auf das CMS (WooCommerce über REST) treffe, und dann ähnlich umgekehrt, indem ich Cookies für den Client innerhalb des Knotens setze Server. Es ist kompliziert, aber es ist fast geschafft!
– Allan aus Sydney
16. Juli 2018 um 10:18 Uhr