vue-resource interceptor for auth headers - vue.js

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()
});

Related

401 Unauthorized error in Express API post request

I am trying to develop the logic for a POST route handler in Express. I put the following together:
const headers = {
"Authorization":"TS Token asdfghjk-asdf-4567-fghjkl; tid=onfido-token";
"content-type": "application/json"
};
const params = {
"policy_request_id": "onfido_applicantandtoken"
};
app.get("/get_stuff", (req, res) => {
axios
.post("https://third/party/api", {
headers,
params
})
.then(function (response) {
res.json(response.data);
})
.catch(function (error) {
res.json("Error occured!");
});
}
});
I keep getting a 401 Unauthorized for the above. On Postman it works, but with the logic above I get a 401 Unauthorized, specifically in the logs I would get Header 'Authorization' not found or Could not parse authorization header. So I am unclear as to what could be going on with the header.
A lot of posts talk about req.headers, but my req.headers does not have the Authorization token and content-type in there, it has some other token that the API I am trying to connect to I assume needs to reach out to another API.
I have refactored it to look like this:
app.get("/get_stuff", (req, res) => {
axios
.post("https://third/party/api", params, headers)
.then(function (response) {
res.json(response.data);
})
.catch(function (error) {
res.json("Error occured!");
});
}
});
And I am still getting the same exact error.
To be clear the params is not something that gets passed into the URL on Postman, but rather the body of the postman request.
I was able to get it to successfully connect by declaring a global axios default like so:
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
as documented here:
https://www.npmjs.com/package/axios#user-content-config-defaults

How to pass header in axios request?

I'm trying to implement Laravel Cashier and Stripe Subscriptions into my Laravel and Vue js SPA. I'm using Laravel Passport and jwt for authentication. I found an article online on how do this.
Whenever I click "Pay" button I get 401 Unauthorized error and when I click on URL in Network tab it gives error unauthenticated.
I think the issue is because I'm not passing the 'Authorization': 'Bearer '+auth.getAccessToken() in the headers when trying to access those routes.
Here is the method from the article:
loadIntent(){
axios.get('/api/v1/user/setup-intent')
.then( function( response ){
this.intentToken = response.data;
}.bind(this));
},
Here is what I tried, but this doesn't seem to be working:
loadIntent(){
const headers = {
'Authorization': 'Bearer '+auth.getAccessToken(),
};
axios.get('/api/v1/user/setup-intent', {
headers: headers
})
.then( function( response ){
this.intentToken = response.data;
}.bind(this));
},
Any idea what the issue is?

Problem setting API client authorization key in axios

The API is developed using Laravel, I am currently implementing authorization logic using Laravel Passport. the client application is a Vuejs application, Http calls are done using axios.
Passport is perfectly returning a token (i'm using client credentials type of grants). axios offers a way to set default headers by setting axios.defaults.headers.common array. Here is my axios call (implemented in bootstrap.js)
async function a() {
var ret = "";
await axios
.post("/oauth/token", {
"client_id": 7,
"client_secret": "2GmvfxQev7AnUyfq0Srz4jJaMQyWSt1iVZtukRR6",
"grant_type": "client_credentials",
"scope": "*"
})
.then((resp) => {
ret = resp.data.access_token;
})
return ret;
}
a().then((res) => {
console.log(res) //this perfectly loggs the token to the console.
axios.defaults.headers.common["Authorization"] = "Bearer " + res
})
However, all subsequent axios calls are missing the Bearer token header.
You may try to create an axios instance with custom config:
https://github.com/axios/axios#creating-an-instance
Example:
const axios = require('axios').create({
headers: {
'Authorization': 'Bearer: ' + token
}
});
and use it just like you would normally do:
axios.get(url).then(resp => {
//response handler
});
axios.post(url, data).then(resp => {
//response handler
});

Accessing the response from one GET request within another

I'm working with Vue to interact with an external API on a Drupal website, but in order to do so dynamically per Drupal user, I need to get a token from Drupal first. To do so, I'm trying to do two GET requests. The first gets me a bearer token out of Drupal, and the second uses it to authenticate the third-party API request.
Below is what I'm trying – I'm able to get the token successfully in the first request's response, but not when I try to use it in the header of my second request. If I try hardcoding the token that I see in the console log, it does work, so I know none of that is the issue. It's just that this.jwt['data']['token'] in the second request's headers seems to not pull back the token.
What do I need to adjust in order to access the token from the first response as part of the headers of my second request?
created() {
axios
.get('/jwt/token')
.then(response => {
this.jwt = response
console.log(this.jwt['data']['token']) // this does show what I want to access later
})
},
mounted() {
axios
.get('/comment/doc/' + this.id, {
headers: { Authorization: "Bearer " + this.jwt['data']['token'] } // ...but this doesn't work
})
.then(response => {
this.comments = response
})
},
It's likely the response to the token request has not finished by the time the component mounts, at which point this.jwt is not yet assigned.
I would move the token request into the mounted hook, fetching comments only when the token request succeeds:
export default {
mounted() {
axios
.get('/jwt/token')
.then(tokenResp => {
this.jwt = tokenResp
axios
.get('/comment/doc/' + this.id, {
headers: { Authorization: 'Bearer ' + this.jwt['data']['token'] }
})
.then(commentsResp => {
this.comments = commentsResp
})
})
}
}

axios.post not sending auth header (but .get does)

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