在 React Native 中使用授权 header 和 Fetch

Using an authorization header with Fetch in React Native

我正在尝试在 React Native 中使用 fetch 从 Product Hunt API 中获取信息。我已经获得了正确的访问令牌并将其保存到状态,但似乎无法在 GET 请求的授权 header 中传递它。

这是我目前的情况:

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. 之后,我会将 this.stateclientToken 属性 设置为等于收到的访问令牌。
  3. 然后,我将 运行 getPosts 应该 return 包含来自 Product Hunt 的一系列当前帖子的响应。

我能够验证正在接收访问令牌,并且 this.state 正在接收它作为它的 clientToken 属性。我还能够验证 getPosts 是 运行.

我收到的错误如下:

{"error":"unauthorized_oauth", "error_description":"Please supply a valid access token. Refer to our api documentation about how to authorize an api request. Please also make sure you require the correct scopes. Eg \"private public\" for to access private endpoints."}

我一直在假设我没有在我的授权中正确传递访问令牌 header,但似乎无法弄清楚原因。

原来是我用错了fetch方法

fetch 需要两个参数:API 的端点和可选的 object,它可以包含 body 和 headers.

我在一秒钟内 object 包装了预期的 object,但没有得到任何想要的结果。

这是它在高层次上的样子:

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

我的 object 结构如下:

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

授权获取示例 header:

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

我遇到了同样的问题,我使用 django-rest-knox 作为身份验证令牌。事实证明,我的 fetch 方法没有任何问题,如下所示:

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

我是 运行 apache。

为我解决这个问题的方法是在 wsgi.conf 中将 WSGIPassAuthorization 更改为 'On'

我在 AWS EC2 上部署了一个 Django 应用程序,我使用 Elastic Beanstalk 来管理我的应用程序,所以在 django.config 中,我这样做了:

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

如果您使用不记名令牌,则以下代码片段应该有效:

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