javascript - Använda en auktoriseringsheader med Fetch i React Native


Jag försöker använda fetch i React Native för att hämta information från Product Hunt API. Jag har fått rätt åtkomsttoken och har sparat den i State, men verkar inte kunna skicka med den inom Authorization-headern för en GET-förfrågan.

Här är vad jag har hittills:

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();
  },

Förväntningen jag har på min kod är följande:

  1. Först kommer jag att hämta en åtkomsttoken med data från min importerade API-modul
  2. Efter det kommer jag att sätta clientToken-egenskapen i this.state till att vara lika med det åtkomsttoken som mottagits.
  3. Sedan kommer jag att köra getPosts vilket bör returnera ett svar som innehåller en array med aktuella inlägg från Product Hunt.

Jag kan bekräfta att åtkomsttoken tas emot och att this.state tar emot det som sin clientToken-egenskap. Jag kan också bekräfta att getPosts körs.

Felet jag får är följande:

{"error":"unauthorized_oauth", "error_description":"Vänligen tillhandahåll en giltig åtkomsttoken. Se vår API-dokumentation om hur man auktoriserar en API-förfrågan. Se också till att du begär de korrekta behörigheterna. T.ex. \"private public\" för att få tillgång till privata slutpunkter."}

Jag har arbetat utifrån antagandet att jag på något sätt inte skickar vidare åtkomsttokenet korrekt i min auktoriseringsheader, men verkar inte kunna lista ut exakt varför.

Svar #1

Exempel på fetch med auktoriseringshuvud:

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

Svar #2

Det visar sig att jag använde fetch-metoden felaktigt.

fetch accepterar två parametrar: en endpoint till API:et och ett valfritt objekt som kan innehålla body och headers.

Jag höll på att slå in det avsedda objektet i ett andra objekt, vilket inte gav mig något önskat resultat.

Så här ser det ut på en hög nivå:

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

Jag strukturerade mitt alternativobjekt på följande sätt:

    var options = {  
      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'
      })
    }

Svar #3

Följande kodavsnitt bör fungera om du använder bärartoken:

const token = localStorage.getItem('token')

const response = await fetch(apiURL, {
    method: 'POST',
    headers: {
        'Content-type': 'application/json',
        'Authorization': `Bearer ${token}`, // notice the Bearer before your token
    },
    body: JSON.stringify(yourNewData)
})

Svar #4

Jag hade detta identiska problem, jag använde django-rest-knox för autentiseringstoken. Det visade sig att det inte var något fel på min fetch-metod som såg ut så här:

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

Jag körde Apache.

Vad som löste detta problem för mig var att ändra WSGIPassAuthorization till 'On' i wsgi.conf.

Jag hade en Django-app driftsatt på AWS EC2, och jag använde Elastic Beanstalk för att hantera min applikation, så i django.config gjorde jag detta:

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

Relaterade artiklar