Scarica API con cookie


201

Sto provando la nuova API Fetch ma sto riscontrando problemi con i cookie. In particolare, dopo un accesso riuscito, c'è un'intestazione Cookie nelle richieste future, ma Fetch sembra ignorare quelle intestazioni e tutte le mie richieste fatte con Fetch non sono autorizzate.

È perché Fetch non è ancora pronto o Fetch non funziona con i cookie?

Costruisco la mia app con Webpack. Uso anche Fetch in React Native, che non presenta lo stesso problema.

Risposte:


280

Fetch non utilizza i cookie per impostazione predefinita. Per abilitare i cookie, procedere come segue:

fetch(url, {
  credentials: "same-origin"
}).then(...).catch(...);

55
la stessa origine non funziona più, include include (vedi la risposta di
@Jerry

7
@jpic: 'include' funziona solo per le richieste di origine incrociata, ma non per le richieste della stessa origine. Documenti ufficiali: github.com/github/fetch#sending-cookies
HoldOffHunger

Qual è la ragione quindi per avere i cookie httponly se sono leggibili in js con fetch?
Martin Bajcar,

4
Credo same-origin(che funziona ancora) significa che verranno rispettate più intestazioni (cookie, ecc.) Ma il tuo codice avrà un accesso limitato alla risposta.
Coderer,

2
@JohnBalvinAriasThx. Come ho capito in seguito, avere i cookie httponly significa che non è leggibile da document.cookie, ma è ancora disponibile per ajax o recuperare richieste.
Martin Bajcar,

186

Oltre alla risposta di @ Khanetor, per coloro che stanno lavorando con richieste di origine incrociata: credentials: 'include'

Richiesta di recupero JSON di esempio:

fetch(url, {
  method: 'GET',
  credentials: 'include'
})
  .then((response) => response.json())
  .then((json) => {
    console.log('Gotcha');
  }).catch((err) => {
    console.log(err);
});

https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials


9
come si imposta il cookie però?
pomo,

2
Il cookie è impostato dal lato server. Nel mio caso stavo usando i cookie httponly.
Khanetor,

3
@Khanetor posso impostare i cookie utilizzando document.cookie tramite javascript e quindi inviare la richiesta?
ospitante

@ospider Puoi inviarlo nell'intestazione.
10101010,

2
@ospider Ho scoperto che la sola impostazione del valore document.cookieera sufficiente per essere inclusa nelle richieste.
skwidbreth,

36

Ho appena risolto. Solo due f. giorni di brutalità

Per me il segreto era nel seguente:

  1. Ho chiamato POST / api / auth e ho visto che i cookie sono stati ricevuti con successo.

  2. Quindi chiamando GET / api / users / with credentials: 'include'e ottenuto 401 unauth, a causa della mancanza di cookie con la richiesta.

Il TASTO deve essere impostato anche credentials: 'include'per la prima /api/authchiamata.


1
Ho esattamente il tuo problema. Il cookie di sessione non viene mai inviato sulla richiesta di dati GET. così 401. Ho provato Axios e Fetch. stesso risultato. 2 possibilità: il POST di accesso non memorizza il cookie ricevuto o i seguenti dati GET non inviano il cookie memorizzato
Rabarbaro65

@ Rhubarb65, per vincere devi specificare credentials: 'include'per primoPOST /api/auth
user1671599

Sì, l'ho avuto ma lo vuole abbastanza. Uso un proxy devserver (client Http)
Rhubarb65,

Sì, avevo le credenziali ma non era abbastanza. Stavo usando un proxy devserver per superare CORS: (client http) - proxy - (server https). Credo che ciò significhi che il cookie sessionid dal server non è stato impostato nel browser perché i cookie sicuri richiedono https. Quindi ho aggiunto il flag https: true nel proxy devserver e questo è stato corretto
Rhubarb65,

1
Bene salute. La tua risposta significava che mi ci è voluto solo 1 giorno di bruteforce. :)
Michael,

16

Se stai leggendo questo nel 2019, credentials: "same-origin"è il valore predefinito.

fetch(url).then

1
Ma nota che non tutti usano un browser sufficientemente aggiornato. Mi sono imbattuto in questa domanda perché la mia versione di Firefox (60.x, la più recente in Debian Stretch) non la imposta di default.
phil

2

Basta aggiungere alle risposte corrette qui per gli .net webapi2utenti.

Se si utilizza corsperché il sito client è servito da un indirizzo diverso dal proprio, webapiè necessario includere anche SupportsCredentials=truenella configurazione lato server.

        // Access-Control-Allow-Origin
        // https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api
        var cors = new EnableCorsAttribute(Settings.CORSSites,"*", "*");
        cors.SupportsCredentials = true;
        config.EnableCors(cors);

0

Questo funziona per me:

import Cookies from 'universal-cookie';
const cookies = new Cookies();

function headers(set_cookie=false) {
  let headers = {
    'Accept':       'application/json',
    'Content-Type': 'application/json',
    'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
};
if (set_cookie) {
    headers['Authorization'] = "Bearer " + cookies.get('remember_user_token');
}
return headers;
}

Quindi crea la tua chiamata:

export function fetchTests(user_id) {
  return function (dispatch) {
   let data = {
    method:      'POST',
    credentials: 'same-origin',
    mode:        'same-origin',
    body:        JSON.stringify({
                     user_id: user_id
                }),
    headers:     headers(true)
   };
   return fetch('/api/v1/tests/listing/', data)
      .then(response => response.json())
      .then(json => dispatch(receiveTests(json)));
    };
  }
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.