React Native에서 Fetch와 함께 인증 헤더 사용


141

fetchProduct Hunt API의 정보를 얻기 위해 React Native에서 사용하려고합니다 . 적절한 액세스 토큰을 얻어 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 문서를 참조하십시오. 또한 올바른 범위가 필요한지 확인하십시오. 예 :" "개인 공개 \" "개인 엔드 포인트에 액세스합니다."}

인증 헤더에서 액세스 토큰을 올바르게 전달하지 않는다는 가정을 수행했지만 그 이유를 정확히 알 수없는 것 같습니다.


2
이 SO 에서 언급했듯이 헤더는 소문자로 작성되었습니다 (일부 서버는 이것을 존중하고 다른 서버는 그렇지 않습니다). 나 자신을 알지 못하여 물 렸기 때문에 공유하고 문제를 디버깅하는 데 시간을 낭비했습니다. 많은 프로젝트, 예제 및 기사가 이것을 존중하지 않는 것 같습니다.
tj

@tj 헤더 이름은 대소 문자를 구분하지 않으며, 링크 된 질문에 대해 + 허용 된 대답과 대답입니다.
coreyward

답변:


195

인증 헤더가있는 페치 예 :

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

7
@RonRoyston OPTIONS 통화를보고 있습니까? API 엔드 포인트에 CORS가 사용 가능하지 않은 경우 (Access-Control-Allow-Origin : * 다른 도메인에서 액세스하는 경우) OPTIONS 호출에서 실패 할 수 있습니다.
코디 모 니즈

1
api endpoint는 CORS를 사용하도록 설정하지 않았기 때문에 아마도 작동하지 않습니다. 감사. 파이어 폭스에 대한 'cors everywhere'애드온을 설치하고 작동했습니다.
Ronnie Royston

3
@RonRoyston이보고있는 문제를 다시 살펴보면 노드 고유의 것이 아닌 btoa 라이브러리를 가져와야 합니다. (브라우저 라이브러리의 포트입니다.) 그렇지 않으면 인증 헤더 작성이 자동으로 실패합니다. 우리도 같은 일을 겪고있었습니다.
Freewalker

2
developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch 문서마다 헤더를 다음과 같이 감싸 야합니다.new Headers()
Daniel Dubovski

67

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

현재 작동하는 코드를 제공 할 수 있습니까? 인증 헤더와 함께 가져 오기를 사용하려고하는데 401응답이 있기 때문에 인증 코드가 헤더로 전달되지 않는다고 생각 합니다.
GoldenBeet

2
도움이 되길 바랍니다
Richard Kho

1
오, 나는 그 예와 함께 당신의 개인 사이트에 있었다! 그것이 제가 처음으로 모델링 한 방법입니다. 그래도 내 문제를 알아 냈습니다. 내 URL이 잘못되었다는 것입니다. /마지막에 내가 빠진 것이 필요했습니다 ...
GoldenBeet

1
감사합니다. 도움이되었습니다. 가져 오기 문서에서 가져 오기가 쿠키를 처리하지 않는다고 지적하는 동안이 코드를 사용하여 쿠키를 헤더에 수동으로 추가 할 수도 있습니다. uid와 키를 저장하고 var obj = {메소드 : 'GET', 헤더 : { 'Accept': 'application / json', 'Content-Type': 'application / json', 'Cookie': '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 => {
...

나는 아파치를 뛰고 있었다.

내가 어떻게이 문제를 해결하는 것은 변화했다 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.