JWT expired with fetch javascript - javascript

What is the best way with pure javascript fetch function to check if JWT has expired that is being passed in authorization header before making a request to get data?
const headers = new Headers({
'Content-Type': 'application/json',
Authorization: 'Bearer GrabbedFromParamQueryString'
});
const settings = {
method: 'GET',
headers: headers
};
fetch('/info/user, settings).then(response => {
console.log(response.json());
});
I know in jQuery you can do a precheck if it has expired then generate a new token then continue with the original request. Is there something like that with Javascript fetch if so how?
Any help would be appreciated.

I was able to achieve this by checking the status of the response which gave me the answer if it was expired or not. Once I had that information created a handled error function and do the next set of action to grab the new refresh and token id.

try
console.log(response.json());
if(response.msg=== "Token is expired"){
alert('token is already expired, login again')
}
});
Atleast thats what I do for jwt extended tokens , because they generate such a response. so in your case, If you used some other naming type like "message" please go ahead and use it to loop through your response. I hope its been of help.

Related

POST request to Spotify API saying no token

I am getting this error message when I am trying a POST request:
{
"error": {
"status": 401,
"message": "No token provided"
}
}
The thing is I am passing in an access token by making a headers variable and assigning it to the headers for the post request like this:
const headers = {
Authorization: `Bearer ${accessToken}`
}
return fetch(`https://api.spotify.com/v1/users/${userId}/playlists`, {
'headers': headers,
method: 'POST',
body: JSON.stringify({'name': name})
This fetch request is the one giving me the error I stated above. How can I fix this?
Headers object picture right before the fetch request
Here is the link to the GitHub: https://github.com/aoljaca/jamming
This code is in the src/utils/Spotify document
Thanks!
I tried running your code but it threw a different error before it it was able to reach that part of your program.
One possible debugging strategy is making sure the headers variable is still defined and includes the access key before returning the fetch request. Just print it to console before running that particular fetch. If it goes out of scope at some point in your promise chain then it could be null.
I'd also suggest using headers: headers instead of 'headers': headers.

How can I get basic auth information from browser

My backend needs basic auth Authorization header.
'Authorization': 'Basic dXNlcm5hbWU6cGFzc3dvcmQ'
The problem I have is, that I need to use the native basic auth prompt from the browser and I don't know how to get the basic auth info in my javascript frontend application. In other words: I need to get the username and password from the browsers basic auth propmt.
Can anyone tell me how to get the basic auth info from the browsers native basic auth prompt?
To get a token request from backend( like login request) in response you will get token thne use can save in s
// Store
sessionStorage.setItem("Authorization", "dXNlcm5hbWU6cGFzc3dvcmQ");
// Retrieve
let token = sessionStorage.getItem("Authorization");
For API call use fetch
For add Authorization header code
let token = sessionStorage.getItem("Authorization");
var headers = new Headers();
headers.append("Authorization", "Basic " +token;
fetch("https://url", {
headers: headers
})
.then((response) => { ... })
.done();

Unsupported grant type when getting OAuth token for Reddit API

I'm trying to get an OAuth token for the Reddit API following the Application Only OAuth instructions. My reddit app is an installed app, so for my grant_type I'm using https://oauth.reddit.com/grants/installed_client.
Currently I'm running a very short JS script to query the API and get a token:
const APP_ID = 'MY_APP_ID'
const DEVICE_ID = 'TRACKING_ID_20_TO_30_CHARS'
let form = new FormData()
form.append('grant_type', 'https://oauth.reddit.com/grants/installed_client')
form.append('device_id', DEVICE_ID)
fetch('https://www.reddit.com/api/v1/access_token', {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Basic ${btoa(`${APP_ID}:`)}`,
}),
body: form })
.then(handleResponse)
.then(function(data) {
console.log(data)
})
.catch(error => console.error(error))
function handleResponse(response) {
return response.json()
}
(Note: running the snippet as-is will give you a NetworkError because the APP_ID isn't a real one and I don't want to give mine out.)
The response I get is:
{
"error": "unsupported_grant_type"
}
When I try the same API request using a REST client I get back the expected response, so this makes me think that the problem is JavaScript-related. Since the grant_type matches what the instructions say I'm not really sure what to do with the error. I'm hoping someone else more experienced with OAuth will know what is going on here.
The problem was the use of the FormData object. In earlier stages of troubleshooting I found this answer on Reddit and decided to use it, but that didn't work for me.
It was submitting the data as multipart/form-data rather than application/x-www-form-urlencoded, which Reddit's OAuth server did not like. I wrote a helper function based on this answer which did the trick:
function urlEncode(data) {
let out = [];
for (let key in data) {
out.push(`${key}=${encodeURIComponent(data[key])}`);
}
return out.join('&')
}

POST Request Using fetch() Returns 204 No Content

I'm making a POST request to a node.js server and I'm having trouble getting it to work. Here's my request:
const headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'this-can-be-anything',
};
export const postVote = (id, vote) =>
fetch(`${uri}/posts/${id}`, {
method: 'POST',
headers,
body: JSON.stringify({options: vote}),
}).then(response => response.json())
.then(data => data)
.catch(err => console.log(err));
The function accepts an 'id' and a 'vote', both strings. The id is being used as part of the URI in the request, and the vote is being supplied as options so the API knows what to do with it. Both of the arguments are being passed correctly:
id = '8xf0y6ziyjabvozdd253nd'
vote = 'upVote'
Here's a link to the GitHub repository for the server/API:
Udacity Readable API
and a screenshot of the network when firing the request:
UPDATE: Added the second screenshot which shows status 200. Though it shows this and appears to have been successful, it still doesn't post to the server and the information stays the same.
What you are looking at is the OPTIONS request in the network tab. For cross origin requests, every request if preceeded by an OPTIONS request which tells the calling client (browser, for example) if those HTTP methods are supported by the remote server for use in crosss origin context.
Check the other requests out. If the OPTIONS request was responded to correctly by the server, the browser must automatically follow up with your POST request
EDIT:
Also, the docs specify the param name to be option whereas in your screenshot it is coming up as options.
Further reading: CORS
Try declaring the headers as such:
var headers = new Headers({
'Content-Type': 'application/json',
'Authorization': 'this-can-be-anything',
})

Configuration for vue-resource root and authorization

I'm looking at the following documentation for vue-resource that describes how to set up configuration: https://github.com/vuejs/vue-resource/blob/master/docs/config.md
It says to set your headers with a common authorization value:
Vue.http.headers.common['Authorization'] = 'Basic YXBpOnBhc3N3b3Jk';
I am guessing this "Basic YXBpOnBhc3N3b3Jk" value is just an example, but what is this value for, and what should one use instead of it?
On the same page, I also see a setting for "root":
Vue.http.options.root = '/root';
I understand this to mean the web URL for the web app. However, why does vue-resource need me to tell it this value? What does it use it for?
By adding headers to the Vue.http.headers.common object you are telling vue-resource to add these headers in every request.
You can also add headers to each request:
http({
url: '/someUrl',
method: 'GET',
headers: {
Authorization: 'Basic YXBpOnBhc3N3b3Jk'
}
})
About the value for the Authorization header in the example: It is a base64-encoded string with username/password.
window.atob('YXBpOnBhc3N3b3Jk') // => "api:password"
If you need to use basic authentication when using vue-resource, you should provide your own username/password.
Note that everyone who is using you application can view the username/password.
See https://en.wikipedia.org/wiki/Basic_access_authentication for more information about basic authentiaction.
The root-property could be the main endpoint to your REST-service.
Instead of:
http({
url: 'http://api.domain.com/v1/someRoute'
});
You could set the root endpoint with:
Vue.http.options.root = 'http://api.domain.com/v1'
// will call http://api.domain.com/v1/someRoute
http({
url: '/someRoute'
});
If you want set header auth in global way use the inceptor
Vue.http.interceptors.push(function(request, next) {
request.headers['Authorization'] = 'Basic abcd' //Base64
request.headers['Accept'] = 'application/json'
next()
});
and use option credentials:
Vue.http.options.credentials = true;

Categories

Resources