This may be a newbiew question (I haven't used the fetch api before), but I can't figure out what wrong with my request.
fetch('https://securetoken.googleapis.com/v1/token?key=' + API_KEY, {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'grant_type=refresh_token&refresh_token=' + refreshToken
})
.then(response => console.log(response))
.catch(error => console.error(error))
I'm trying to exchange a refresh token for an id token following the guidelines here, but for some reason I'm getting a Bad Request response...
Response { type: "cors", url: "https://securetoken.googleapis.com/v1/token?key=[API_KEY]", redirected: false, status: 400, ok: false, statusText: "Bad Request", headers: Headers, body: ReadableStream, bodyUsed: false }
My key is correct, and the refreshToken is also straight from a response from a service on Firebase SDK.
Where exactly is my mistake?
UPDATE
Showing the context where fetch is executed in a Next.js app:
I'm running this code in dev (localhost) using Firebase Emulators.
I managed to find additional error logs that state { code: 400, message: "INVALID_REFRESH_TOKEN", status: "INVALID_ARGUMENT" }.
So, this indeed seems to be an issue with the refresh_token. Can it be because it has been emitted by Firebase Emulators?
useEffect(() => {
return firebase.auth().onIdTokenChanged(async user => {
if (user) {
fetch('https://securetoken.googleapis.com/v1/token?key=' + process.env.NEXT_PUBLIC_FIREBASE_API_KEY, {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'grant_type=refresh_token&refresh_token=' + user.refreshToken
})
.then(response => console.log(response))
.catch(error => console.error(error))
}
})
}, [])
In the end the cause for the issue was the fact that the refreshToken issued when using Firebase Emulators is not valid when exchanging for an idToken.
Quite an edge case, but perhaps someone may find this helpful.
Related
I'm pretty new to working with API's, and I'm currently trying to fetch some data from the Spotify API in a Next.js website.
The problem is that the only end-point that gives me any data is the 'top-tracks': (https://api.spotify.com/v1/me/top/tracks), all the other end-points I've tried gives this error:
Request failed FetchError: invalid json response body at https://api.spotify.com/v1/me/player/recently-played reason: Unexpected token U in JSON at position 0
This is the function I'm using to fetch data from the API:
const basic = Buffer.from(`${client_id}:${client_secret}`).toString("base64");
const TOKEN_ENDPOINT = `https://accounts.spotify.com/api/token`;
export default async function handler(req, res) {
const response = await fetch(TOKEN_ENDPOINT, {
method: "POST",
headers: {
Authorization: `Basic ${basic}`,
"Content-Type": "application/x-www-form-urlencoded",
},
body: querystring.stringify({
grant_type: "refresh_token",
refresh_token,
}),
})
.then((response) => response.json())
.then((data) => {
const access_token = data.access_token;
return fetch(`https://api.spotify.com/v1/me/player/recently-played`, {
method: "GET",
headers: {
Authorization: `Bearer ${access_token}`,
},
});
})
.then((response) => response.json())
.catch((err) => {
console.error("Request failed", err);
});
return res.status(200).json(response);
}
(First getting the access token, using clientId and secret from env-variables, then fetching data from API using said token)
Any idea of what I'm doing wrong here? All help is greatly appreciated :)
Also:
I've added the necessary scopes, so I should have permisssion to get the data!
I am working on user authentication using web tokens in react. I am using fetch() to make a POST request to my backend using CORS. Trying to use setToken() hook inside the .then() gives an error. I tried storing the token to another variable, and using setToken() outside the promise, but to no avail. Here's the code:
const [ token, setToken ] = useState('')
// Configuration for POST fetch method
const url = 'http://localhost:8080/users/login'
const requestOptions = {
method: 'POST',
headers: { 'Content-type': 'application/json' },
body: JSON.stringify(userData)
}
let tempToken = ''
fetch(url, requestOptions)
.then(res => res.json())
.then(data => {
tempToken = data.token
// console.log(tempToken) // DEBUG
})
.catch(e => console.log(e))
setToken(tempToken)
// console.log(token) // This logs default value of token, which is ''
This is all inside a function. What is going wrong here? Also is there another way to do this, much appreciated. Thanks.
What is my problem: Cannot extract token from promise.
P.S: Also, on a completely different note, I tried using async await but it gave a response (shown below), where I couldn't even find the body of the json. Hence using .then()
Response {type: "cors", url: "http://localhost:8080/users/login", redirected: false, status: 200, ok: true, …}
body: (...)
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: "OK"
type: "cors"
url: "http://localhost:8080/users/login"
__proto__: Response
Fetch returns a promise, you need wait to get the token and then use setToken. Moreover you're calling fetch directly and updating the state even before rendering, that might leads to warnings/side effects. You can use useEffect hook to call api and update the state
useEffect(() => {
const url = 'http://localhost:8080/users/login'
const requestOptions = {
method: 'POST',
headers: { 'Content-type': 'application/json' },
body: JSON.stringify(userData)
}
fetch(url, requestOptions)
.then(res => res.json())
.then(data => {
setToken(data.token)
})
.catch(e => console.log(e))
}, [])
I need to request POST method to authorize and set current location of user in my react-native application. As authorization header,I add token which I get before from API and saved it to the state. However, when I make request, I get error message of auth header empty. Whereas, when I console.log the token, it prints correctly. I guess the issue is something about the type of token. I tried to convert it to string, but nothing changed.
By the way, I checked request with static token - copy&pasted token instead of this.state.token and it worked perfectly, so it is clear that I live problem with converting the token.
Here is the code that I make request.
console.log("AUTH TOKEN: ", this.state.token);
var Url = "https://-----------";
return fetch(Url, {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + this.state.token
},
body: JSON.stringify({'latitude': this.state.location.coords.latitude.toString(), 'longitude': this.state.location.coords.longitude.toString()})
})
// .then((response) => response.json())
.then((response) => {
console.log(response);
})
.done();
here is the result of request on console.
Has anyone lived such issue before?
After following the documentation on GitHub's API, I got stuck on submitting a comment for a gist, the following code always returns 404, and the same call made in Postman too.
My JavaScript code as follows:
const config = {
method: 'POST',
headers: {
'Authorization': credentials.authorizationHeader,
'Content-Type': 'application/vnd.github.v3.text+json'
},
body: { "body": JSON.stringify(comment) }
};
fetch(`https://api.github.com/gists/${gistId}/comments/`, config)
.then(res => {
if (res.ok) {
dispatch(getGistDetails(gistId, credentials));
dispatch({ type: SUBMIT_COMMENT_SUCCESS });
} else {
ToastAndroid.show('An error ocurred, please try again.', ToastAndroid.SHORT);
console.log(res);
dispatch({ type: SUBMIT_COMMENT_FAIL });
}
})
.catch(err => console.log(err));
Credentials I'm getting via OAuth:
accessToken: "redacted"
authorizationHeader:"bearer redacted"
clientID:"redacted"
idToken:null
scopes:"gist"
type:"bearer"
I tried changing the authorizationHeader to token <oauth_token, but still no success.
Thanks in advance.
Looks like you have some non standard characters in your GIST ID that are not even visible and I can't even get your link to work ( or is it private? )
Turns out I was overcomplicating, as getting a gist's details through the API also nets you a comments_url field with the correct url, so no need to splice strings, falling into the very strange issue mentioned by #Zilvinas below. Also, a minor adjustment in the body to
const body = { body: comment }
const config = {
method: 'POST',
headers: {
'Authorization': credentials.authorizationHeader,
'Content-Type': 'application/vnd.github.v3.text+json'
},
body: JSON.stringify(body)
};
fixed the subsequent Problems parsing JSON error I got.
I am posting the details of user in api ,using the access token in header which i got in sign up but getting this error --> Unexpected end of JSON input. My code is
postNameToApi()
{
console.log("inside post api");
fetch('https://MyPostApi', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization':'Bearer'+'Qwjubq41KAWw9uI2NMj4TPQ9t24PxC'
},
body: JSON.stringify({
dob:'1992-04-18',
gender: 'femanino',
is_professional:true,
is_referee:false
})
}).then((response) => response.json())
.then((responseData) => {
console.log("inside responsejson");
console.log('response:',responseData);
//this.setState({response:responseData});
}).done();
}
This is because your response is not in json format. Space is missing between Bearer and your token, i think this will solve your issue.
'Authorization':'Bearer '+'Qwjubq41KAWw9uI2NMj4TPQ9t24PxC'
Try your api call with postman first.