Używanie nagłówka autoryzacji z Fetch in React Native


141

Próbuję użyć fetchw React Native, aby pobrać informacje z API Product Hunt. Uzyskałem właściwy token dostępu i zapisałem go w stanie, ale wydaje się, że nie mogę go przekazać w nagłówku autoryzacji dla żądania GET.

Oto, co mam do tej pory:

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

Oczekiwania, jakie mam wobec mojego kodu, są następujące:

  1. Najpierw będę fetchtokenem dostępu z danymi z mojego zaimportowanego modułu API
  2. Następnie ustawię clientTokenwłaściwość this.staterówną otrzymanemu tokenowi dostępu.
  3. Następnie uruchomię, getPostsktóra powinna zwrócić odpowiedź zawierającą tablicę aktualnych postów z Product Hunt.

Jestem w stanie zweryfikować, czy token dostępu jest odbierany i czy this.stateotrzymuje go jako swoją clientTokenwłasność. Jestem również w stanie sprawdzić, czy getPostsjest uruchamiany.

Otrzymuję następujący błąd:

{"error": "unauthorized_oauth", "error_description": "Podaj prawidłowy token dostępu. Zapoznaj się z naszą dokumentacją API, aby dowiedzieć się, jak autoryzować żądanie API. Upewnij się również, że potrzebujesz poprawnych zakresów. Np. \" private public \ „w celu uzyskania dostępu do prywatnych punktów końcowych”.}

Odpracowałem założenie, że w jakiś sposób nie przekazuję poprawnie tokenu dostępu w nagłówku autoryzacji, ale nie potrafię dokładnie określić, dlaczego.


2
Jak wspomniano w tym SO , nagłówki powinny być pisane małymi literami (niektóre serwery to szanują, inne nie). Udostępniam tylko dlatego, że ugryzło mnie to, nie wiedząc siebie (i straciłem czas na próbę debugowania problemu). Szkoda, że tak wiele projektów, przykładów i artykułów wydaje się tego nie uwzględniać.
tj

@tj W nazwach nagłówków nie jest rozróżniana wielkość liter i dokładnie tak mówi zaakceptowana + najlepsza odpowiedź na pytanie, które łączysz.
coreyward

Odpowiedzi:


195

Przykładowe pobieranie z nagłówkiem autoryzacji:

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
To nie działa dla mnie. 'Authorization'Nagłówek cicho nie przywiązują za Firebug. Próbowałem nawet dołączyć credentials: 'include'do opcjonalnego obiektu.
Ronnie Royston,

7
@RonRoyston. Patrzysz na wezwanie OPTIONS? jeśli punkt końcowy interfejsu API nie ma włączonego mechanizmu CORS (Access-Control-Allow-Origin: * w przypadku uzyskiwania dostępu z innej domeny), może to zakończyć się niepowodzeniem przy wywołaniu OPTIONS.
Cody Moniz

1
Punkt końcowy API nie ma włączonego CORS, więc prawdopodobnie dlatego nie zadziałał dla mnie. Dzięki. Skończyło się na zainstalowaniu dodatku „cors wszędzie” do przeglądarki Firefox i zadziałało.
Ronnie Royston,

3
Jeśli chodzi o problem, który widzi @RonRoyston, musisz zaimportować bibliotekę btoa , która nie jest natywna dla węzła. (Jest to port biblioteki przeglądarki.) W przeciwnym razie utworzenie nagłówka auth po cichu kończy się niepowodzeniem. Doświadczyliśmy tego samego.
Freewalker

2
developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch per docs, trzeba zawijać nagłówkinew Headers()
Daniel Dubovski

67

Okazuje się, że fetchźle użyłem tej metody.

fetch oczekuje dwóch parametrów: punktu końcowego API i opcjonalnego obiektu, który może zawierać treść i nagłówki.

Pakowałem wybrany obiekt w drugi obiekt, co nie przyniosło mi pożądanego rezultatu.

Oto jak to wygląda na wysokim poziomie:

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

Skonstruowałem mój obiekt jako taki:

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

czy możesz podać działający kod? Próbuję użyć funkcji pobierania z nagłówkiem autoryzacji i nie sądzę, aby mój kod autoryzacji był przekazywany jako nagłówek, ponieważ otrzymuję 401odpowiedź.
GoldenBeet

2
Gotowe, mam nadzieję, że to pomoże
Richard Kho

1
Och, byłem na twojej osobistej stronie z tym przykładem! Tak modelowałem swój pierwszy raz. Zrozumiałem jednak mój problem, po prostu mój adres URL był nieprawidłowy. Na /koniec brakowało mi ...
GoldenBeet

1
Dzięki, to było pomocne. Warto zauważyć, że chociaż dokumentacja pobierania wskazuje, że pobieranie nie obsługuje plików cookie, możesz ręcznie dodać pliki cookie do nagłówka również za pomocą tego kodu. Po prostu zapisz identyfikator i klucz i wykonaj coś takiego: var obj = {metoda: 'GET', headers: {'Accept': 'application / json', 'Content-Type': 'application / json', 'Cookie': 'uid =' + uid + '; key = '+ key});
Dustin

8

Miałem ten sam problem, używałem django-rest-knox do uwierzytelniania tokenów. Okazuje się, że nie było nic złego w mojej metodzie pobierania, która wyglądała tak:

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

Biegałem apache.

To, co rozwiązało ten problem, zmieniło się WSGIPassAuthorizationna 'On'w wsgi.conf.

Miałem aplikację Django wdrożoną na AWS EC2 i użyłem Elastic Beanstalk do zarządzania moją aplikacją, więc w programie django.configzrobiłem to:

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);
        });
};
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.