Buscar API com Cookie

198

Estou experimentando a nova API de busca, mas está tendo problemas com os cookies. Especificamente, após um login bem-sucedido, há um cabeçalho de Cookie em solicitações futuras, mas a Fetch parece ignorar esses cabeçalhos e todas as minhas solicitações feitas com a Fetch não são autorizadas.

É porque o Fetch ainda não está pronto ou o Fetch não funciona com os Cookies?

Eu construo meu aplicativo com o Webpack. Também uso a opção Buscar no React Native, que não tem o mesmo problema.

Khanetor
fonte

Respostas:

279

A busca não usa cookies por padrão. Para habilitar o cookie, faça o seguinte:

fetch(url, {
  credentials: "same-origin"
}).then(...).catch(...);
Khanetor
fonte
55
de mesma origem não funciona mais, incluem não (ver resposta da @ Jerry): developers.google.com/web/updates/2015/03/introduction-to-fetch
JPIC
7
@jpic: 'include' funciona apenas para solicitações de origem cruzada, mas não para solicitações de mesma origem. Documentos oficiais: github.com/github/fetch#sending-cookies
HoldOffHunger
Qual é o motivo, então, de ter cookies de reposição, caso sejam legíveis em js com busca?
Martin Bajcar
4
Eu acredito same-origin(que faz ainda trabalho) significa que mais cabeçalhos serão respeitados (biscoitos, etc.), mas seu código terá acesso limitado à resposta.
Coderer
2
@JohnBalvinAriasThx. Como entendi mais tarde, ter o cookie updponly significa que não é legível por document.cookie, mas ainda está disponível para solicitações de ajax ou busca.
Martin Bajcar
183

Além da resposta de @ Khanetor, para aqueles que trabalham com solicitações de origem cruzada: credentials: 'include'

Exemplo de solicitação de busca JSON:

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

zurfyx
fonte
9
como você define o cookie?
pomo
2
O cookie é definido no lado do servidor. No meu caso, eu estava usando cookies de reposição.
Khanetor
3
@Khanetor posso definir cookies usando o document.cookie por javascript e depois enviar a solicitação?
ospider
@ospider Você pode enviá-lo no cabeçalho.
10101010
2
@ospider Achei que apenas definir o valor document.cookieera suficiente para ser incluído nos pedidos.
Skwidbreth 2/04
35

Acabaram de resolver. Apenas dois f. dias de força bruta

Para mim, o segredo estava no seguinte:

  1. Liguei para POST / api / auth e verifique se os cookies foram recebidos com sucesso.

  2. Em seguida, chame GET / api / users / with credentials: 'include'e obtenha 401 sem autenticação, pois nenhum cookie foi enviado com a solicitação.

A tecla é para definir também credentials: 'include'para a primeira /api/authchamada.

user1671599
fonte
1
Eu tenho exatamente o seu problema. O cookie da sessão nunca é enviado na solicitação de dados GET. 401. Tentei o Axios e o Fetch. mesmo resultado. 2 possibilidades: a loja de login POST doesnt o cookie recebido ou os seguintes dados GET does not enviar o cookie armazenado
Rhubarb65
@ Rhubarb65, para ganhar isso, você deve especificar credentials: 'include'primeiroPOST /api/auth
user1671599
Sim, eu tinha isso, mas ele quer o suficiente. Eu uso um proxy devserver (cliente HTTP)
Rhubarb65
Sim, eu tinha credenciais, mas não foi suficiente. Eu estava usando um proxy devserver para passar pelo CORS: (cliente http) - proxy - (servidor https). Acredito que isso significava que o cookie sessionid do servidor não estava definido no navegador porque os cookies seguros exigem https. Então eu adicionei a bandeira https: true no proxy devserver e que fixa-lo
Rhubarb65
1
Bem saúde. Sua resposta significou que me levou apenas 1 dia de força bruta. :)
Michael
15

Se você está lendo isso em 2019, credentials: "same-origin"é o valor padrão.

fetch(url).then
alextrastero
fonte
Mas observe que nem todos estão usando um navegador suficientemente atualizado. Me deparei com essa pergunta porque minha própria versão do Firefox (60.x, a mais recente no Debian Stretch) não define isso por padrão.
Phill #
2

Apenas adicionando aqui as respostas corretas para os .net webapi2usuários.

Se você estiver usando corsporque o site do cliente é veiculado a partir de um endereço diferente do seu webapi, precisará incluir também SupportsCredentials=truena configuração do servidor.

        // 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);
Mark Dornian
fonte
0

Isso funciona para mim:

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;
}

Em seguida, faça sua ligação:

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)));
    };
  }
aarkerio
fonte