Fai in modo che Axios invii automaticamente i cookie nelle sue richieste


121

Sto inviando richieste dal client al mio server Express.js utilizzando Axios.

Ho impostato un cookie sul client e voglio leggere quel cookie da tutte le richieste di Axios senza aggiungerli manualmente alla richiesta manuale.

Questo è il mio esempio di richiesta lato cliente:

axios.get(`some api url`).then(response => ...

Ho provato ad accedere alle intestazioni o ai cookie utilizzando queste proprietà nel mio server Express.js:

req.headers
req.cookies

Nessuno dei due conteneva cookie. Sto utilizzando il middleware del parser dei cookie:

app.use(cookieParser())

Come posso fare in modo che Axios invii automaticamente i cookie nelle richieste?

Modificare:

Ho impostato il cookie sul client in questo modo:

import cookieClient from 'react-cookie'

...
let cookie = cookieClient.load('cookie-name')
if(cookie === undefined){
      axios.get('path/to/my/cookie/api').then(response => {
        if(response.status == 200){
          cookieClient.save('cookie-name', response.data, {path:'/'})
        }
      })
    }
...

Sebbene utilizzi anche Axios, non è rilevante per la domanda. Voglio semplicemente incorporare i cookie in tutte le mie richieste una volta impostato un cookie.


1
come hai impostato il cookie sul client? mostra un esempio di codice per favore :)
Tzook Bar Noy

@TzookBarNoy Aggiunto codice in questione
Kunok

I cookie vengono impostati dai server con Set-Cookie non dal client, immagino che tu intenda leggere il cookie sul client. Secondo il protocollo Cookie, il client dovrebbe includere un'intestazione Cookie nelle sue richieste al server di emissione del cookie.
Hans Poo

Risposte:


241

Ho avuto lo stesso problema e l'ho risolto utilizzando la withCredentialsproprietà.

XMLHttpRequest da un dominio diverso non può impostare i valori dei cookie per il proprio dominio a meno che withCredentials non sia impostato su true prima di effettuare la richiesta.

axios.get('some api url', {withCredentials: true});

8
Se stai tentando di connetterti a un'app Express, dovrai utilizzare cors e utilizzare queste impostazioni. L'origine della richiesta è obbligatoria. app.use (cors ({credentials: true, origin: ' localhost: 8080 '}));
DogCoffee

17
nota che questo funzionerà solo quando l' Access-Control-Allow-Originintestazione in response non è impostata su carattere jolly (*)
Jerry Zhang

1
@ JerryZhang Cosa intendi? Sto affrontando lo stesso problema, se Access-Control-Allow-Originnon è impostato *significa che non farò richiesta a quel server a causa del corretto CORS
samayo

5
La risposta deve impostare Access-Control-Allow-Originil valore sul dominio da cui si desidera effettuare la richiesta XHR. ad esempio https://a.comè il server, https://b.comè il client, https://b.comviene caricato nel browser di qualcuno e sta utilizzando XMLHTTPRequestper fare richiesta a https://a.com. Inoltre per la XMLHTTPRequest(avviato nel https://a.com) al set withCredential: true, il server - https://b.comdeve anche essere configurato in modo l'intestazione di risposta contieneAccess-Control-Allow-Origin: https://a.com
Jerry Zhang

Ho un piccolo problema con questo ... se ho a come server b come client (es. Pagina di reazione), allora se lo imposto su true, invierà le credenziali a, non le credenziali b ... LOL. .. OK, non è divertente.
golddragon007

24

TL; DR:

{ withCredentials: true } o axios.defaults.withCredentials = true


Dalla documentazione di Axios

withCredentials: false, // default

withCredentials indica se le richieste di controllo degli accessi tra siti devono essere effettuate utilizzando le credenziali

Se passi { withCredentials: true }con la tua richiesta dovrebbe funzionare.

Un modo migliore sarebbe impostare withCredentialscome trueinaxios.defaults

axios.defaults.withCredentials = true


5
L'invio di credenziali a ogni richiesta è una cattiva pratica. Questi controlli sono in atto per un motivo. Parlare con un altro servizio, inviare tutti i tuoi cookie, indipendentemente dal fatto che vengano utilizzati, è maturo per lo sfruttamento.
colm.anseo

2
@colminator verranno inviati solo i cookie che hanno il dominio del server come dominio. (Per impostazione predefinita non verranno nemmeno inviati a nessun sottodominio e possono esserci ulteriori filtri in base al percorso.) In effetti stiamo inviando solo i cookie del server che sono stati impostati dal server.
M3RS

15

Non ho familiarità con Axios, ma per quanto ne so in javascript e ajax c'è un'opzione

withCredentials: true

Questo invierà automaticamente il cookie al lato client. Ad esempio, questo scenario viene generato anche con passportjs, che imposta un cookie sul server


11

È anche importante impostare le intestazioni necessarie nella risposta rapida. Questi sono quelli che hanno funzionato per me:

app.use(function(req, res, next) {
  res.header('Access-Control-Allow-Origin', yourExactHostname);
  res.header('Access-Control-Allow-Credentials', true);
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
  next();
});

L'aggiunta X-PINGOTHERa Access-Control-Allow-Headersè stata obbligatoria per me (Node.js 6.9 con Express 4.16, Chrome 63). Controlla il post di JakeElder su questo problema di GitHub: github.com/axios/axios/issues/191#issuecomment-311069164
Frosty Z


5

per le persone ancora non in grado di risolverlo, questa risposta mi ha aiutato. risposta stackoverflow: 34558264

TLDR; è necessario impostare {withCredentials: true}sia la richiesta GET che la richiesta POST (ottenere il cookie) sia per gli assi sia per il recupero.


1
Questo è fondamentale. Avevo trascurato questo nel mio codice e ho passato molto tempo a chiedermi perché la { withCredentials: true }richiesta GET non avesse alcun effetto.
yogmk

1
Estremamente importante! Ci sono molte discussioni sull'aggiunta withCredentials: truealla configurazione della richiesta ma non su questo dettaglio. Ho passato quasi 2 giorni cercando di risolvere il problema fino a quando non mi sono imbattuto in questo
R. Antao il

4

Come posso fare in modo che Axios invii automaticamente i cookie nelle richieste?

impostato axios.defaults.withCredentials = true;

oppure per qualche specifica richiesta puoi utilizzare axios.get(url,{withCredentials:true})

questo darà l'errore CORS se il tuo "Access-Control-Allow-Origin" è impostato su carattere jolly (*). Assicurati quindi di specificare l'URL di origine della tua richiesta

ad esempio: se il tuo front-end che effettua la richiesta viene eseguito su localhost: 3000, imposta l'intestazione della risposta come

res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');

anche impostato

res.setHeader('Access-Control-Allow-Credentials',true);

3

È possibile utilizzare la withCredentialsproprietà per passare i cookie nella richiesta.

axios.get(`api_url`, { withCredentials: true })

IMPOSTANDO { withCredentials: true } potresti riscontrare problemi di origine incrociata. Per risolverlo devi usare

expressApp.use(cors({ credentials: true, origin: "http://localhost:8080" }));

Qui puoi leggere informazioni su withCredentials


2

Stai mescolando i due pensieri.

Hai "react-cookie" e "axios"

react-cookie => serve per gestire il cookie sul lato client

axios => serve per inviare richieste ajax al server

Con queste informazioni, se desideri che i cookie dal lato client vengano comunicati anche dal lato backend, dovrai collegarli insieme.

Nota dal file Readme di "react-cookie":

Biscotti isomorfi!

Per poter accedere ai cookie dell'utente durante il rendering del server, è possibile utilizzare plugToRequest o setRawCookie.

collegamento a readme

Se questo è ciò di cui hai bisogno, bene.

In caso contrario, per favore commenta così potrei elaborare di più.


Cosa fa plugToRequestesattamente? Ho pensato di accedere ai cookie sul server del nodo, tutto ciò di cui hai bisogno è il cookie-parsermiddleware (assumendo Express)?
geoboy

2

Quindi ho avuto lo stesso identico problema e ho perso circa 6 ore della mia vita a cercare, ho avuto il file

withCredentials: true

Ma il browser non ha ancora salvato il cookie fino a quando per qualche strano motivo ho avuto l'idea di mescolare le impostazioni di configurazione:

Axios.post(GlobalVariables.API_URL + 'api/login', {
        email,
        password,
        honeyPot
    }, {
        withCredentials: true,
        headers: {'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json'
    }});

Sembra che dovresti sempre inviare prima la chiave "withCredentials".

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.