I'm sending GET request to the same endpoint with the same headers, including the Bearer, but while i get 200 and the correct JSON as a result when calling from Postman, when i send the request using Axios in my (Vue) project i get 302.
the call from the local project , running on localhost:8080 (in case its useful) is as follows:
const { authToken, userID } = store.getters.authUser
const config = {
method: 'get',
url: '/' + userID,
headers: {
Authorization: `Bearer ${authToken}`,
'Content-Type': 'application/json'
}
}
axios(config)
.then(res => {
console.log(res)
return res
})
.catch(e => {
console.log(e)
})
while in postman all i do is create a GET request with the same url and all i add in the headers is the 'Bearer ...'
the error i get from axios is :
Error: Network Error
at createError (createError.js?2d83:16)
at XMLHttpRequest.handleError (xhr.js?b50d:87)
and response status is 302 , any idea whats going on here??
both values of userID and the authToken exists and are equal to the same values i used with postman, same goes for the url
Related
I'm working through this tutorial on creating an app that uses the Spotify API. Everything was going great until I got to the callback portion of authenticating using the authentication code flow.
(I do have my callback URL registered in my Spotify app.)
As far as I can tell, my code matches the callback route that this tutorial and others use. Significantly, the http library is axios. Here's the callback method:
app.get("/callback", (req, res) => {
const code = req.query.code || null;
const usp = new URLSearchParams({
code: code,
redirect_uri: REDIRECT_URI,
grant_type: "authorization_code",
});
axios({
method: "post",
url: "https://accounts.spotify.com/api/token",
data: usp,
headers: {
"content-type": "application/x-www-form-urlencoded",
Authorization: `Basic ${new Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString("base64")}`,
},
})
.then(response => {
console.log(response.status); // logs 200
console.log(response.data); // logs encoded strings
if (response.status === 200) {
res.send(JSON.stringify(response.data))
} else {
res.send(response);
}
})
.catch((error) => {
res.send(error);
});
Though the response code is 200, here's a sample of what is getting returned in response.data: "\u001f�\b\u0000\u0000\u0000\u0000\u0000\u0000\u0003E�˒�0\u0000Ee�uS\u0015��\u000e�(\b\u0012h\u0005tC%\u0010\u0014T\u001e�����0��^:���p\u0014Ѻ\u000e��Is�7�:��\u0015l��ᑰ�g�����\u0"
It looks like it's encoded, but I don't know how (I tried base-64 unencoding) or why it isn't just coming back as regular JSON. This isn't just preventing me logging it to the console - I also can't access the fields I expect there to be in the response body, like access_token. Is there some argument I can pass to axios to say 'this should be json?'
Interestingly, if I use the npm 'request' package instead of axios, and pass the 'json: true' argument to it, I'm getting a valid token that I can print out and view as a regular old string. Below is code that works. But I'd really like to understand why my axios method doesn't.
app.get('/callback', function(req, res) {
// your application requests refresh and access tokens
// after checking the state parameter
const code = req.query.code || null;
const state = req.query.state || null;
const storedState = req.cookies ? req.cookies[stateKey] : null;
res.clearCookie(stateKey);
const authOptions = {
url: 'https://accounts.spotify.com/api/token',
form: {
code: code,
redirect_uri: REDIRECT_URI,
grant_type: 'authorization_code',
},
headers: {
Authorization: `Basic ${new Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString('base64')}`,
},
json: true,
};
request.post(authOptions, function (error, response, body) {
if (!error && response.statusCode === 200) {
const access_token = body.access_token;
const refresh_token = body.refresh_token;
var options = {
url: 'https://api.spotify.com/v1/me',
headers: { Authorization: 'Bearer ' + access_token },
json: true,
};
// use the access token to access the Spotify Web API
request.get(options, function(error, response, body) {
console.log(body);
});
// we can also pass the token to the browser to make requests from there
res.redirect('/#' + querystring.stringify({
access_token: access_token,
refresh_token: refresh_token,
}));
} else {
res.redirect(`/#${querystring.stringify({ error: 'invalid_token' })}`);
}
});
});
You need to add Accept-Encoding with application/json in axios.post header.
The default of it is gzip
headers: {
"content-type": "application/x-www-form-urlencoded",
'Accept-Encoding': 'application/json'
Authorization: `Basic ${new Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString("base64")}`,
}
I'm working on a project with Vue using the Spotify API and get stuck trying to get the access token. I'm using axios to make the request but every time I get a 400 status from the server.
This is the way I'm doing it, I have the request inside an action in my Vuex store and I'm not sure if I'm missing something.
axios({
method: 'post',
url: 'https://accounts.spotify.com/api/token',
params: {
grant_type: 'authorization_code',
code: payload.code,
redirect_uri: process.env.VUE_APP_REDIRECT_URI
},
headers: {
'Authorization': 'Basic ' + (new Buffer(process.env.VUE_APP_CLIENT_ID + ':' + process.env.VUE_APP_CLIENT_SECRET).toString('base64')),
'Content-Type': 'application/x-www-form-urlencoded'
},
json: true
})
.then((response) => {
//handle success
resolve(response);
})
.catch((error) => {
//handle error
reject(error);
})
I would try using data instead of params.
I think data is for the POST body and params is for query string parameters.
Axios Cheat Sheet
You should inspect the request to see what you're sending and then compare that to what you should be sending.
I run the axios get method to call php script.but request send twice
how to solve this problem.
myfunction:-
axios.get('http://13.233.179.174/customers_log.php',{
headers: {
'Access-Control-Allow-Origin': '*'
},
})
.then(function (response) {
$("#spinner").hide();
console.log('this is response work');
console.log(response.data);
})
.catch(function (error) {
$("#spinner").hide();
console.log(error);
})
It'a Preflight request
It is an OPTIONS request, using three HTTP request headers: Access-Control-Request-Method, Access-Control-Request-Headers, and the Origin header.
Check here - https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
I am using axios in my Vue project, and one of the calls to my api involves a POST. Both my posts and gets require that the Authorization header be set with my token. All get requests work fine, but putting the exact same headers in axios.post results in a 403.
Here is my axios code:
axios.post('https://my.example.org/myapi/meta?uname=' + uname + '&umetaid=' + post.umeta_id + '&umetavalue=' + post.meta_value, {
withCredentials: true,
headers: { 'Authorization': 'Bearer ' + mytoken }
})
.then(function (response) {
console.log(response)
})
.catch(function (error) {
console.log(error)
})
This always results in a 403 error, and checking my request headers show that the Authorization header is never sent. If I change axios.post to axios.get above (and add a GET method to my api code, in addition to the existing POST,OPTIONS), it will execute just fine. I suppose I could leave it this way, but I think it is bad practice to use a GET call when one really is performing a POST. Is there something I am missing about forming a POST request with axios?
Axios Post request assumes that the second parameter is data and third parameter is config.
Axios Get request assumes that the second parameter is config while the data is appended in URL.
You are sending data in the url which should be as second parameter(For POST request).
Code Should be:
var data = {
'uname': uname,
'umetaid': post.umeta_id,
'umetavalue': post.meta_value
}
var headers = {
withCredentials: true,
headers: { 'Authorization': 'Bearer ' + mytoken }
}
axios.post('https://my.example.org/myapi/meta',data,headers)
.then(function (response) {
console.log(response)
})
.catch(function (error) {
console.log(error)
})
I am trying to set up a Vuejs fronted application (vue-cli webpack template) to sit on top of my Laravel API.
I am able to get a successful response from the API with vue-resource by providing the correct auth token, for example:
methods: {
getUser () {
this.$http.get('http://localhost:8000/api/user',
{
headers: {
'Authorization': 'Bearer eyJ0e.....etc',
'Accept': 'application/json'
}
}).then((response) => {
this.name = response.data.name
});
},
However, I am now trying to set up interceptors so that the user's auth token will automatically be added for each request.
Based on the vue-resource readme I am trying this in my main.js:
Vue.use(VueResource)
Vue.http.interceptors.push((request, next) => {
request.headers['Authorization'] = 'Bearer eyJ0e.....etc'
request.headers['Accept'] = 'application/json'
next()
})
And then back in my component I now just have:
this.$http.get('http://localhost:8000/api/user').then((response) => {
this.name = response.data.name
});
Problem:
When I specify the headers in the get itself, I get a successful response, but when I pass them through the interceptor I get back a 401 Unauthorized from the server. How can I fix this to respond successfully while using the interceptor?
Edit:
When I use dev-tools to view the outgoing requests I see the following behavior:
When making the request by supplying the headers to $http.get, I make a successful OPTIONS request and then a successful GET request with the Authentication header being supplied to the GET request.
However, when I remove the headers from the $http.get directly and move them to the interceptor, I only make a GET request and the GET does not contain the Authentication header, thus it comes back as a 401 Unauthorized.
It turns out my problem was the syntax for which I was setting the headers in the interceptor.
It should be like this:
Vue.use(VueResource)
Vue.http.interceptors.push((request, next) => {
request.headers.set('Authorization', 'Bearer eyJ0e.....etc')
request.headers.set('Accept', 'application/json')
next()
})
While I was doing this:
Vue.use(VueResource)
Vue.http.interceptors.push((request, next) => {
request.headers['Authorization'] = 'Bearer eyJ0e.....etc'
request.headers['Accept'] = 'application/json'
next()
})
Add this option:
Vue.http.options.credentials = true;
And use the interceptors for global way:
Vue.http.interceptors.push(function(request, next) {
request.headers['Authorization'] = 'Basic abc' //Base64
request.headers['Accept'] = 'application/json'
next()
});