Menggunakan header otorisasi dengan Fetch in React Native

148

Saya mencoba menggunakan fetchdi React Native untuk mengambil informasi dari API Perburuan Produk. Saya telah memperoleh Token Akses yang tepat dan telah menyimpannya ke Status, tetapi tampaknya tidak dapat meneruskannya dalam header Otorisasi untuk permintaan GET.

Inilah yang saya miliki sejauh ini:

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

Harapan yang saya miliki untuk kode saya adalah sebagai berikut:

  1. Pertama, saya akan fetchmendapatkan token akses dengan data dari modul API yang saya impor
  2. Setelah itu, saya akan mengatur clientTokenproperti this.statemenjadi sama dengan token akses yang diterima.
  3. Kemudian, saya akan menjalankan getPostsyang seharusnya mengembalikan respons yang berisi larik posting saat ini dari Product Hunt.

Saya dapat memverifikasi bahwa token akses telah diterima dan this.statemenerimanya sebagai clientTokenpropertinya. Saya juga dapat memverifikasi bahwa getPostssedang dijalankan.

Kesalahan yang saya terima adalah sebagai berikut:

{"error": "unauthorized_oauth", "error_description": "Berikan token akses yang valid. Lihat dokumentasi api kami tentang cara mengotorisasi permintaan api. Pastikan juga Anda memerlukan cakupan yang benar. Misalnya \" private public \ "untuk mengakses titik akhir pribadi."}

Saya telah mengerjakan asumsi bahwa saya entah bagaimana tidak meneruskan token akses dengan benar di header otorisasi saya, tetapi tampaknya tidak dapat mengetahui dengan tepat mengapa.

Richard Kho
sumber
2
Seperti disebutkan dalam SO ini , header dimaksudkan dalam huruf kecil (beberapa server menghormati ini, yang lain tidak.) Saya hanya berbagi karena saya digigit olehnya tanpa mengetahui diri saya sendiri (dan membuang-buang waktu mencoba men-debug masalah.) Sangat disayangkan bahwa begitu banyak proyek, contoh, dan artikel yang tampaknya tidak menghargai hal ini.
tj
@tj Nama header tidak peka huruf besar / kecil, dan itulah yang dikatakan jawaban atas + yang diterima pada pertanyaan yang Anda tautkan.
Coreyward

Jawaban:

205

Contoh pengambilan dengan header otorisasi:

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'
 });
Cody Moniz
sumber
4
Ini tidak berhasil untuk saya. The 'Authorization'sundulan diam-diam gagal untuk melampirkan per pembakar. Saya bahkan sudah mencoba memasukkan credentials: 'include'objek opsional.
Ronnie Royston
7
@RonRoyston apakah Anda melihat panggilan OPTIONS? jika titik akhir API tidak mengaktifkan CORS (Access-Control-Allow-Origin: * jika mengakses dari domain yang berbeda), maka mungkin gagal pada panggilan OPTIONS.
Cody Moniz
1
api endpoint tidak mengaktifkan CORS, jadi itu mungkin mengapa itu tidak berhasil untuk saya. Terima kasih. Saya akhirnya menginstal add-on 'cors everywhere' untuk firefox dan berhasil.
Ronnie Royston
3
Re masalah yang dilihat @RonRoyston, Anda perlu mengimpor pustaka btoa , yang bukan asli node. (Ini adalah port lib browser.) Jika tidak, pembuatan header auth akan gagal secara diam-diam. Kami mengalami hal yang sama.
Freewalker
2
developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch per dokumen, perlu new Headers()
menggabungkan
70

Ternyata, saya salah menggunakan fetchmetode tersebut.

fetch mengharapkan dua parameter: titik akhir ke API, dan objek opsional yang dapat berisi isi dan header.

Saya membungkus objek yang dimaksud dalam objek kedua, yang tidak memberi saya hasil yang diinginkan.

Berikut tampilannya pada level tinggi:

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

Saya menyusun objek saya seperti:

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'
  })
Richard Kho
sumber
bisakah Anda memberikan kode yang sekarang berfungsi? Saya mencoba menggunakan pengambilan dengan header otorisasi dan saya rasa kode autentikasi saya tidak diteruskan sebagai header, karena saya mendapatkan 401respons.
GoldenBeet
2
Selesai, semoga bermanfaat
Richard Kho
1
Oh, saya pernah mengunjungi situs pribadi Anda dengan contoh itu! Begitulah cara saya memodelkan milik saya untuk pertama kalinya. Saya menemukan masalah saya, hanya saja url saya salah. Ini membutuhkan /pada akhirnya bahwa saya hilang ...
GoldenBeet
1
Terima kasih, ini sangat membantu. Perlu dicatat bahwa meskipun dokumentasi pengambilan menunjukkan bahwa pengambilan tidak menangani cookie, Anda juga dapat menambahkan cookie ke header secara manual dengan kode ini. Simpan saja uid dan kunci dan lakukan sesuatu seperti: var obj = {metode: 'GET', header: {'Accept': 'application / json', 'Content-Type': 'application / json', 'Cookie': 'uid =' + uid + '; key = '+ key});
Dustin
9

Saya mengalami masalah yang sama, saya menggunakan django-rest-knox untuk token otentikasi. Ternyata tidak ada yang salah dengan metode pengambilan saya yang terlihat seperti ini:

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

Saya menjalankan apache.

Apa yang memecahkan masalah ini bagi saya berubah WSGIPassAuthorizationmenjadi 'On'masuk wsgi.conf.

Saya memiliki aplikasi Django yang diterapkan di AWS EC2, dan saya menggunakan Elastic Beanstalk untuk mengelola aplikasi saya, jadi di django.config, saya melakukan ini:

container_commands:
  01wsgipass:
    command: 'echo "WSGIPassAuthorization On" >> ../wsgi.conf'
Marquistador
sumber
-1
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);
        });
};
lilash sah
sumber