Використання заголовка авторизації з Fetch in React Native


141

Я намагаюся використовувати fetchв React Native для отримання інформації з API полювання на продукт. Я отримав належний маркер доступу і зберег його в штаті, але, схоже, не зможе передати його в заголовку авторизації для GET-запиту.

Ось що я маю досі:

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

Очікування, яке я маю на свій код, таке:

  1. По-перше, я отримаю fetchмаркер доступу з даними з мого імпортного модуля API
  2. Після цього я встановлю clientTokenвластивість this.stateдорівнювати отриманому маркеру доступу.
  3. Потім я запускаю, getPostsякий повинен повернути відповідь, що містить масив поточних публікацій від Product Hunt.

Я маю змогу переконатися, що маркер доступу отримано та this.stateчи отримує він його як clientTokenвласність. Я також можу переконатися, що getPostsце запущено.

Я отримую помилку наступну:

{"error": "unauthorized_oauth", "error_description": "Будь ласка, надайте дійсний маркер доступу. Зверніться до нашої документації api про те, як авторизувати запит api. Будь ласка, переконайтеся, що вам потрібні правильні області застосування. Наприклад, \" приватний публічний \ "для доступу до приватних кінцевих точок."}

Я опрацьовую припущення, що я якось не проходжу належним чином маркер доступу в своєму заголовку авторизації, але, здається, не можу точно зрозуміти, чому саме.


2
Як зазначається в цьому ТА , заголовки призначені для малих букв (деякі сервери це поважають, інші - ні.) Я поділяюсь лише тому, що мене вкусив, не знаючи себе (і витрачав час, намагаючись налагодити проблему.) Прикро, що тому багато проектів, прикладів та статей, схоже, цього не поважають.
TJ

Імена заголовка @tj не відрізняються від регістру, і саме це відповідає прийнята + найвища відповідь на відповідне вами питання.
coreyward

Відповіді:


195

Приклад отримання із заголовком авторизації:

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
Це не працює для мене. 'Authorization'Тема мовчки не вдається прилаштувати в палій. Я навіть намагався включати credentials: 'include'в необов'язковий об’єкт.
Ронні Ройстон

7
@RonRoyston Ви дивитесь на дзвінок ВАРІАНТІВ? якщо в кінцевій точці API не ввімкнено CORS (Access-Control-Allow-Origin: * при доступі з іншого домену), вона може не працювати при виклику OPTIONS.
Коді Моніз

1
Кінцева точка api не увімкнена CORS, тому, ймовірно, це не працювало для мене. Дякую. Я в кінцевому підсумку встановив надбудову "corswhere" для firefox, і вона спрацювала.
Ронні Ройстон

3
Повторіть проблему @RonRoyston бачите, вам потрібно імпортувати бібліотеку btoa , яка не є власною для вузла. (Це порт вкладки браузера.) Інакше створення заголовка аутентично мовчить не вдається. Ми переживали те саме.
Freewalker

2
developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch за документи, потрібно обгорнути заголовкиnew Headers()
Daniel Dubovski

67

Виявляється, я використовував fetchметод неправильно.

fetch очікує два параметри: кінцеву точку API та необов'язковий об'єкт, який може містити тіло та заголовки.

Я загортав призначений об'єкт всередині другого об'єкта, що не дало мені бажаного результату.

Ось як це виглядає на високому рівні:

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

Я структурував свій об’єкт як такий:

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

ви могли б надати вже працюючий код? Я намагаюсь отримати заголовок з заголовком авторизації, і не думаю, що мій код автентичності передається як заголовок, тому що я отримую 401відповідь.
GoldenBeet

2
Готово, сподіваюся, що це корисно
Річард Хо

1
О, я був на вашому особистому сайті з цим прикладом! Ось так я вперше моделював шахту. Я вирішив свою проблему, проте мій URL-адреса була неправильною. На /завершення було потрібно, що я пропав безвісти ...
GoldenBeet

1
Дякую, це було корисно. Варто зауважити, що, хоча документація щодо завантаження вказує на те, що збірка не обробляє файли cookie, ви можете вручну додати файли cookie до заголовка з цим кодом. Просто збережіть uid та ключ та зробіть щось на зразок: var obj = {method: 'GET', headers: {'Accept': 'application / json', 'Content-Type': 'application / json', 'Cookie': 'uid =' + uid + '; ключ = '+ клавіша});
Дастін

8

У мене була однакова проблема, я використовував django-rest-knox для маркерів аутентифікації. Виявляється, з моїм методом вибору, який виглядав приблизно так, нічого не було.

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

Я запускав апаш.

Що вирішити цю проблему для мене зміни WSGIPassAuthorizationв 'On'в wsgi.conf.

У мене було розгорнуто додаток Django на AWS EC2, і я використовував Elastic Beanstalk, щоб керувати моїм додатком, тому в програмі django.configя зробив це:

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);
        });
};
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.