【问题标题】:Using an authorization header with Fetch in React Native在 React Native 中使用带有 Fetch 的授权标头
【发布时间】:2015-07-24 01:05:32
【问题描述】:

我正在尝试在 React Native 中使用 fetch 从 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. 之后,我会将this.stateclientToken 属性设置为等于收到的访问令牌。
  3. 然后,我将运行 getPosts,它应返回包含 Product Hunt 的当前帖子数组的响应。

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

我收到的错误如下:

{"error":"unauthorized_oauth", "error_description":"请提供有效的访问令牌。有关如何授权 api 请求,请参阅我们的 api 文档。还请确保您需要正确的范围。例如 \" private public\" 用于访问私有端点。"}

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

【问题讨论】:

  • this SO 中所述,标头应为小写(有些服务器尊重这一点,而另一些则不这样做。)我分享只是因为我被它咬了不知道我自己(并且浪费时间尝试调试问题。)不幸的是,这么多项目、示例和文章似乎并不尊重这一点。
  • @t.j.标题名称不区分大小写,这正是您链接的问题中接受的 + 最佳答案所说的内容。
  • 5.5 年后,我像 OP 一样设置了一个 fetch 标头:'Authorization': 'Bearer ' + myJWT, 原来 myJWT 被双引号括起来了! Authorization: Bearer "yadda.yadda.yadda" 在多次尝试解决方案后,我过滤了后端的双引号。

标签: javascript oauth-2.0 react-native fetch-api


【解决方案1】:

使用授权标头获取示例:

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

【讨论】:

  • 这对我不起作用。 'Authorization' 标头默默地无法附加每个萤火虫。我什至尝试在可选对象中包含credentials: 'include'
  • @RonRoyston 你在看 OPTIONS 电话吗?如果 API 端点没有启用 CORS(Access-Control-Allow-Origin: * 如果从不同的域访问),那么它可能会在 OPTIONS 调用中失败。
  • api 端点没有启用 CORS,所以这可能就是它对我不起作用的原因。谢谢。我最终为 Firefox 安装了“无处不在的 cors”插件,并且它起作用了。
  • 关于@RonRoyston 看到的问题,您需要导入 btoa 库,它不是 node 原生的。 (它是浏览器库的一个端口。)否则,auth 标头创建会静默失败。我们遇到了同样的事情。
  • developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch 每个文档,需要用 new Headers() 包装标题
【解决方案2】:

如果您使用的是不记名令牌,以下代码 sn-p 应该可以工作:

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

【讨论】:

    【解决方案3】:

    事实证明,我错误地使用了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'
      })
    }
    

    【讨论】:

    • 你能不能提供现在工作的代码?我正在尝试将 fetch 与授权标头一起使用,但我认为我的身份验证代码没有作为标头传递,因为我收到了 401 响应。
    • 完成,希望对您有所帮助
    • 哦,我在你的个人网站上看到过这个例子!这就是我第一次模拟我的方式。我发现了我的问题,只是我的网址错误。它最后需要一个/,我错过了......
    • 谢谢,这很有帮助。值得注意的是,虽然 fetch 文档指出 fetch 不处理 cookie,但您也可以使用此代码手动将 cookie 添加到标头。只需保存 uid 和密钥并执行以下操作: var obj = { method: 'GET', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', 'Cookie': 'uid='+uid+'; key='+key });
    【解决方案4】:

    我遇到了同样的问题,我使用 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'
    

    【讨论】:

    • django.config 是在项目中还是在 apache 配置中?
    【解决方案5】:
    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);
            });
    };
    

    【讨论】:

      猜你喜欢
      • 2018-10-22
      • 1970-01-01
      • 2017-05-22
      • 2020-11-21
      • 2018-08-26
      • 2020-08-16
      • 1970-01-01
      • 2018-01-14
      • 2021-09-15
      相关资源
      最近更新 更多