React NativeのFetchで認証ヘッダーを使用する


140

fetchReact Nativeで使用してProduct Hunt APIから情報を取得しようとしています。適切なアクセストークンを取得してStateに保存しましたが、GETリクエストのAuthorizationヘッダー内で渡すことができないようです。

ここに私がこれまで持っているものがあります:

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. 次に、getPostsProduct Huntからの現在の投稿の配列を含む応答を返すはずのコマンドを実行します。

アクセストークンthis.stateが受信されており、それがそのclientTokenプロパティとして受信されていることを確認できます。getPosts実行されていることも確認できます。

私が受け取っているエラーは次のとおりです:

{"error": "unauthorized_oauth"、 "error_description": "有効なアクセストークンを指定してください。APIリクエストを承認する方法については、APIのドキュメントを参照してください。正しいスコープが必要であることも確認してください。例:\" private public \ "プライベートエンドポイントにアクセスするため。"}

私はどういうわけか、認証ヘッダーでアクセストークンを適切に渡していないという前提に基づいて取り組んでいますが、その理由を正確に理解できていないようです。


2
このSOで述べたように、ヘッダーは小文字にすることを目的としています(一部のサーバーはこれを尊重し、他のサーバーはそうではありません。)私は自分自身を知らないことに悩まされたために共有するだけです(そして、問題をデバッグするために時間を無駄にしました)。多くのプロジェクト、例、および記事はこれを尊重していないようです。
TJ

@tjヘッダー名では大文字と小文字が区別されません。これは、リンクされた質問に対して受け入れられた+上位の回答のとおりです。
coreyward

回答:


194

認証ヘッダーを使用したフェッチの例:

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'オプションのオブジェクトに含めてみました。
Ronnie Royston、2016

7
@RonRoystonはOPTIONS呼び出しを見ていますか?APIエンドポイントでCORSが有効になっていない場合(Access-Control-Allow-Origin:*別のドメインからアクセスしている場合)、OPTIONS呼び出しで失敗する可能性があります。
Cody Moniz 2016

1
APIエンドポイントではCORSが有効になっていないため、おそらく私には機能しませんでした。ありがとう。私は、Firefox用の「cors everywhere」アドオンをインストールしてしまい、うまくいきました。
Ronnie Royston、2016

3
@RonRoystonが見ている問題については、ノードにネイティブではないbtoaライブラリをインポートする必要があります。(これはブラウザlibのポートです。)そうでない場合、authヘッダーの作成は警告なしに失敗します。私たちは同じことを経験していました。
Freewalker 2017

2
ドキュメントごとにdeveloper.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch、ヘッダーをラップする必要がありますnew Headers()
Daniel Dubovski

67

結局のところ、私はfetchメソッドを誤って使用していました。

fetch は、APIのエンドポイントと、本体とヘッダーを含めることができるオプションのオブジェクトの2つのパラメーターを想定しています。

目的のオブジェクトを2番目のオブジェクトでラップしていましたが、目的の結果が得られませんでした。

高レベルでの外観は次のとおりです。

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

おそらく、現在機能しているコードを提供できますか?Authorizationヘッダーでフェッチを使用しようとしていますが、401応答を取得しているため、認証コードがヘッダーとして渡されていないと思います。
GoldenBeet、2015

2
完了しました。お役に立てば幸いです
リチャードコー

1
ああ、私はあなたの個人的なサイトにその例を示してきました!それが私が初めて私の鉱山をモデル化した方法です。私は私の問題を理解しましたが、それは私のURLが間違っているということだけでした。/最後に、欠けていたaが必要でした...
GoldenBeet

1
ありがとう、これは役に立ちました。フェッチのドキュメントで、フェッチではCookieが処理されないことが指摘されていますが、このコードを使用してヘッダーにCookieを手動で追加することもできます。単にuidとキーを保存して、次のようにします:var obj = {method: 'GET'、headers:{'Accept': 'application / json'、 'C​​ontent-Type': 'application / json'、 'C​​ookie': 'uid =' + uid + '; key = '+ key});
ダスティン

8

これと同じ問題があり、認証トークンにdjango-rest-knoxを使用していました。次のようなfetchメソッドには何も問題がないことがわかります。

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

Apacheを実行していました。

私にとってこの問題を解決したのは、に変更WSGIPassAuthorizationすることでし'On'wsgi.conf

AWS EC2にDjangoアプリをデプロイし、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);
        });
};
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.