Использование заголовка авторизации с Fetch в React Native
Я пытаюсь использовать fetch
в React Native для получения информации из API поиска продуктов. Я получил правильный токен доступа и сохранил его в состояние, но, похоже, не смог передать его в заголовке авторизации для запроса GET.
Вот что у меня так далеко:
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();
},
Ожидание, которое я имею для моего кода, следующее:
- Во-первых, я буду
fetch
токен доступа с данными из моего импортированного модуля API - После этого я установлю
clientToken
собственностьюthis.state
равный полученный токен доступа. - Тогда я побегу
getPosts
который должен вернуть ответ, содержащий массив текущих сообщений от Product Hunt.
Я могу проверить, что токен доступа получен и что this.state
получает его как его clientToken
имущество. Я также могу проверить, что getPosts
выполняется
Я получаю следующую ошибку:
{"error": "unauthorized_oauth", "error_description": "Пожалуйста, предоставьте действительный токен доступа. Обратитесь к нашей документации api о том, как авторизовать запрос api. Также убедитесь, что вам требуются правильные области. Например," private public \" "для доступа к частным конечным точкам."}
Я работал над предположением, что я как-то неправильно передаю токен доступа в своем заголовке авторизации, но, похоже, не могу точно понять, почему.
5 ответов
Оказывается, я использовал 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('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'
});
Следующий фрагмент кода должен работать, если вы используете токен носителя:
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)
})
У меня была такая же проблема, я использовал 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'
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);
});
};