Utilizzo di un'intestazione di autorizzazione con Fetch in React Native


141

Sto cercando di utilizzare fetchReact Native per ottenere informazioni dall'API Product Hunt. Ho ottenuto il token di accesso corretto e l'ho salvato nello stato, ma non riesco a passarlo all'interno dell'intestazione di autorizzazione per una richiesta GET.

Ecco cosa ho finora:

var Products = React.createClass({
  getInitialState: function() {
    return {
      clientToken: false,
      loaded: false
    }
  },
  componentWillMount: function () {
    fetch(api.token.link, api.token.object)
      .then((response) => response.json())
      .then((responseData) => {
          console.log(responseData);
        this.setState({
          clientToken: responseData.access_token,
        });
      })
      .then(() => {
        this.getPosts();
      })
      .done();
  },
  getPosts: function() {
    var obj = {
      link: 'https://api.producthunt.com/v1/posts',
      object: {
        method: 'GET',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json',
          'Authorization': 'Bearer ' + this.state.clientToken,
          'Host': 'api.producthunt.com'
        }
      }
    }
    fetch(api.posts.link, obj)
      .then((response) => response.json())
      .then((responseData) => {
        console.log(responseData);
      })
      .done();
  },

L'aspettativa che ho per il mio codice è la seguente:

  1. Innanzitutto, farò fetchun token di accesso con i dati dal mio modulo API importato
  2. Successivamente, imposterò la clientTokenproprietà di this.stateuguale al token di accesso ricevuto.
  3. Quindi, eseguirò getPostsche dovrebbe restituire una risposta contenente una serie di post correnti da Product Hunt.

Sono in grado di verificare che il token di accesso sia stato ricevuto e che lo this.statestia ricevendo come clientTokenproprietà. Sono anche in grado di verificare che getPostsè in esecuzione.

L'errore che sto ricevendo è il seguente:

{"errore": "unauthorized_oauth", "error_description": "Fornisci un token di accesso valido. Consulta la nostra documentazione API su come autorizzare una richiesta API. Assicurati inoltre di richiedere gli ambiti corretti. Ad esempio" pubblico privato \ "per accedere agli endpoint privati."}

Ho lavorato sul presupposto che in qualche modo non sto passando il token di accesso correttamente nella mia intestazione di autorizzazione, ma non riesco a capire esattamente il perché.


2
Come notato in questo SO , le intestazioni devono essere minuscole (alcuni server lo rispettano, altri no.) Condivido solo perché sono stato morso da esso non conoscendo me stesso (e ho perso tempo a cercare di eseguire il debug del problema). È un peccato che così tanti progetti, esempi e articoli non sembrano rispettarlo.
tj

@tj I nomi delle intestazioni non fanno distinzione tra maiuscole e minuscole, ed è esattamente quello che dice la risposta più accettata + sulla domanda che hai collegato.
coreyward

Risposte:


195

Esempio di recupero con intestazione di autorizzazione:

fetch('URL_GOES_HERE', { 
   method: 'post', 
   headers: new Headers({
     'Authorization': 'Basic '+btoa('username:password'), 
     'Content-Type': 'application/x-www-form-urlencoded'
   }), 
   body: 'A=1&B=2'
 });

4
Questo non funziona per me. L' 'Authorization'intestazione non riesce a collegarsi silenziosamente per firebug. Ho anche provato a includere credentials: 'include'l'oggetto opzionale.
Ronnie Royston il

7
@RonRoyston stai guardando la chiamata OPTIONS? se l'endpoint API non ha CORS abilitato (Access-Control-Allow-Origin: * se si accede da un dominio diverso), potrebbe non riuscire alla chiamata OPTIONS.
Cody Moniz,

1
l'API endpoint non ha CORS abilitato, quindi è probabilmente per questo che non ha funzionato per me. Grazie. Ho finito per installare il componente aggiuntivo 'cors ovunque' per Firefox e ha funzionato.
Ronnie Royston,

3
Per quanto riguarda il problema riscontrato da @RonRoyston, è necessario importare la libreria btoa , che non è nativa per il nodo. (È una porta di una libreria del browser.) In caso contrario, la creazione dell'intestazione di autenticazione fallisce silenziosamente. Stavamo vivendo la stessa cosa.
Freewalker,

2
developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch per documenti, è necessario racchiudere le intestazioni connew Headers()
Daniel Dubovski

67

Si scopre che stavo usando il fetchmetodo in modo errato.

fetch prevede due parametri: un endpoint per l'API e un oggetto opzionale che può contenere body e header.

Stavo avvolgendo l'oggetto desiderato in un secondo oggetto, che non mi ha dato alcun risultato desiderato.

Ecco come appare ad alto livello:

fetch('API_ENDPOINT', OBJECT)  
  .then(function(res) {
    return res.json();
   })
  .then(function(resJson) {
    return resJson;
   })

Ho strutturato il mio oggetto come tale:

var obj = {  
  method: 'POST',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'Origin': '',
    'Host': 'api.producthunt.com'
  },
  body: JSON.stringify({
    'client_id': '(API KEY)',
    'client_secret': '(API SECRET)',
    'grant_type': 'client_credentials'
  })

potresti forse fornire il codice ora funzionante? Sto cercando di utilizzare il recupero con un'intestazione di autorizzazione e non credo che il mio codice di autenticazione venga passato come intestazione, perché sto ricevendo una 401risposta.
GoldenBeet

2
Fatto, spero sia utile
Richard Kho,

1
Oh, sono stato sul tuo sito personale con quell'esempio! È così che ho modellato il mio la prima volta. Ho capito il mio problema però, era solo che il mio url era sbagliato. Alla /fine era necessario che mi mancasse ...
GoldenBeet

1
Grazie, questo è stato utile. Vale la pena notare che mentre la documentazione di recupero indica che il recupero non gestisce i cookie, è possibile aggiungere manualmente i cookie all'intestazione anche con questo codice. Basta salvare uid e chiave e fare qualcosa del tipo: var obj = {metodo: 'GET', intestazioni: {'Accept': 'application / json', 'Content-Type': 'application / json', 'Cookie': 'uid =' + uid + '; chiave = '+ chiave});
Dustin,

8

Ho avuto questo identico problema, stavo usando django-rest-knox per i token di autenticazione. Si scopre che non c'era nulla di sbagliato nel mio metodo di recupero che assomigliava a questo:

...
    let headers = {"Content-Type": "application/json"};
    if (token) {
      headers["Authorization"] = `Token ${token}`;
    }
    return fetch("/api/instruments/", {headers,})
      .then(res => {
...

Stavo correndo Apache.

Ciò che risolto questo problema per me era che cambia WSGIPassAuthorizationa 'On'in wsgi.conf.

Avevo distribuito un'app Django su AWS EC2 e ho usato Elastic Beanstalk per gestire la mia applicazione, quindi in django.config, ho fatto questo:

container_commands:
  01wsgipass:
    command: 'echo "WSGIPassAuthorization On" >> ../wsgi.conf'

0
completed = (id) => {
    var details = {
        'id': id,

    };

    var formBody = [];
    for (var property in details) {
        var encodedKey = encodeURIComponent(property);
        var encodedValue = encodeURIComponent(details[property]);
        formBody.push(encodedKey + "=" + encodedValue);
    }
    formBody = formBody.join("&");

    fetch(markcompleted, {
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: formBody
    })
        .then((response) => response.json())
        .then((responseJson) => {
            console.log(responseJson, 'res JSON');
            if (responseJson.status == "success") {
                console.log(this.state);
                alert("your todolist is completed!!");
            }
        })
        .catch((error) => {
            console.error(error);
        });
};
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.