Sử dụng tiêu đề ủy quyền với Tìm nạp trong React Native


140

Tôi đang cố gắng sử dụng fetchtrong React Native để lấy thông tin từ API sản phẩm. Tôi đã nhận được Mã thông báo truy cập phù hợp và đã lưu nó vào Trạng thái, nhưng dường như không thể chuyển nó theo tiêu đề Ủy quyền cho yêu cầu GET.

Đây là những gì tôi có cho đến nay:

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

Kỳ vọng tôi có cho mã của mình là như sau:

  1. Đầu tiên, tôi sẽ fetchmã thông báo truy cập với dữ liệu từ mô-đun API đã nhập của tôi
  2. Sau đó, tôi sẽ đặt thuộc clientTokentính this.statebằng với mã thông báo truy cập nhận được.
  3. Sau đó, tôi sẽ chạy getPostsđể trả về một phản hồi có chứa một loạt các bài đăng hiện tại từ Product Hunt.

Tôi có thể xác minh rằng mã thông báo truy cập đang được nhận và this.stateđang nhận nó là clientTokentài sản của nó . Tôi cũng có thể xác minh rằng getPostsđang được chạy.

Lỗi tôi nhận được là như sau:

{"error": "trái phép_oauth", "error_description": "Vui lòng cung cấp mã thông báo truy cập hợp lệ. Tham khảo tài liệu api của chúng tôi về cách ủy quyền yêu cầu api. Vui lòng đảm bảo bạn yêu cầu phạm vi chính xác. Ví dụ \" riêng tư \ "để truy cập các điểm cuối riêng tư."}

Tôi đã làm việc với giả định rằng bằng cách nào đó tôi không chuyển mã thông báo truy cập đúng cách trong tiêu đề ủy quyền của mình, nhưng dường như không thể hiểu chính xác tại sao.


2
Như đã lưu ý trong SO này , các tiêu đề được dự định là chữ thường (một số máy chủ tôn trọng điều này, một số máy chủ khác thì không.) Tôi chỉ chia sẻ vì tôi bị cắn bởi nó không biết bản thân mình (và lãng phí thời gian để cố gắng gỡ lỗi.) Thật không may là rất nhiều dự án, ví dụ và bài viết dường như không tôn trọng điều này.
tj

@tj Tên tiêu đề không phân biệt chữ hoa chữ thường và đó chính xác là câu trả lời được chấp nhận + hàng đầu nói về câu hỏi bạn đã liên kết.
coreyward

Câu trả lời:


194

Lấy ví dụ với tiêu đề ủy quyền:

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
Điều này không làm việc cho tôi. Các 'Authorization'tiêu đề âm thầm không để đính kèm cho mỗi con đom đóm. Tôi thậm chí đã thử bao gồm credentials: 'include'trong các đối tượng tùy chọn.
Ronnie Royston

7
@RonRoyston bạn đang xem cuộc gọi TÙY CHỌN? nếu điểm cuối API không kích hoạt CORS (Kiểm soát truy cập-Cho phép-Xuất xứ: * nếu truy cập từ một tên miền khác), thì nó có thể thất bại trong lệnh gọi TÙY CHỌN.
Cody Moniz

1
điểm cuối api không kích hoạt CORS, vì vậy đó có thể là lý do tại sao nó không hoạt động với tôi. Cảm ơn. Cuối cùng tôi đã cài đặt tiện ích 'cors ở mọi nơi' cho firefox và nó đã hoạt động.
Ronnie Royston

3
Vấn đề @RonRoyston đang gặp phải, bạn cần nhập thư viện btoa , không phải là nguồn gốc của nút. (Đó là một cổng của một trình duyệt lib.) Nếu không, việc tạo tiêu đề auth âm thầm thất bại. Chúng tôi đã trải qua điều tương tự.
Freewalker

2
developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch cho mỗi tài liệu, cần bọc các tiêu đề vớinew Headers()
Daniel Dubovski

67

Hóa ra, tôi đã sử dụng fetchphương pháp không chính xác.

fetch mong đợi hai tham số: điểm cuối cho API và một đối tượng tùy chọn có thể chứa phần thân và phần đầu.

Tôi đã bọc đối tượng dự định trong một đối tượng thứ hai, điều đó không mang lại cho tôi bất kỳ kết quả mong muốn nào.

Đây là cách nó trông ở mức cao:

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

Tôi cấu trúc đối tượng của mình như vậy:

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

bạn có thể cung cấp mã làm việc bây giờ? Tôi đang cố gắng sử dụng tìm nạp với tiêu đề ủy quyền và tôi không nghĩ mã xác thực của mình đang được chuyển qua làm tiêu đề, bởi vì tôi đang nhận được 401phản hồi.
GoldenBeet

2
Xong, hy vọng nó hữu ích
Richard Kho

1
Oh tôi đã ở trên trang cá nhân của bạn với ví dụ đó! Đó là cách tôi mô hình hóa lần đầu tiên. Tôi đã tìm ra vấn đề của tôi mặc dù, chỉ là url của tôi sai. Nó đòi hỏi một /lúc kết thúc mà tôi nhớ da diết ...
GoldenBeet

1
Cảm ơn, điều này rất hữu ích. Đáng lưu ý rằng trong khi tài liệu tìm nạp chỉ ra rằng tìm nạp không xử lý cookie, bạn cũng có thể thêm cookie vào tiêu đề bằng mã này theo cách thủ công. Chỉ cần lưu uid và khóa và làm một cái gì đó như: var obj = {phương thức: 'GET', tiêu đề: {'Chấp nhận': 'application / json', 'Content-Type': 'application / json', 'Cookie': 'uid =' + uid + '; khóa = '+ khóa});
Dustin

8

Tôi gặp vấn đề tương tự, tôi đang sử dụng django-rest-knox để xác thực mã thông báo. Hóa ra không có gì sai với phương pháp tìm nạp của tôi trông như thế này:

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

Tôi đã chạy apache.

Có gì giải quyết vấn đề này đối với tôi là thay đổi WSGIPassAuthorizationđể 'On'wsgi.conf.

Tôi đã có một ứng dụng Django được triển khai trên AWS EC2 và tôi đã sử dụng Elastic Beanstalk để quản lý ứng dụng của mình, vì vậy, trong đó django.config, tôi đã làm điều này:

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);
        });
};
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.