I am implementing JWT into my Vue application for authorization and I refresh my tokens once they are used.
I have used axios interceptors so I can intercept every request to my API backend and this seems to work on login etc... but once I refresh the page the request is made as normal using the last token.
The problem is the axios interceptors don't seem to work at this point, so once the token has been used I can't update it with the new one.
Here's how I'm setting my interceptors:-
window.axios.interceptors.request.use(function (config) {
console.log("Sent request!");
return config;
}, function (error) {
console.log("Failed sending request!");
return Promise.reject(error);
});
window.axios.interceptors.response.use(function (response) {
console.log("Got headers:", response.headers);
if (response.headers.hasOwnProperty('authorization')) {
console.log("Got authorization:", response.headers.authorization);
Store.auth.setToken(response.headers.authorization);
}
return response;
}, function(err){
console.log("Got error", err);
});
I don't get any of the console.log's on page load.
I am setting my interceptors in the root app's beforeMount method. I've tried moving them to beforeCreate and I still get the same issue.
try this
window.axios.interceptors.request.use(function (config) {
console.log("Sent request!");
if(localStorage.getItem('id_token')!=undefined){
config.headers['Authorization'] = 'Bearer '+localStorage.getItem('id_token')
}
return config;} , function (error) {
console.log("Failed sending request!");
return Promise.reject(error); });
Related
I am using vue js as frontend with laravel. I am using laravel passport for auth, now i wants to show some error message once received 401 unauthentic error message that mostly occurs when my token expired. so to do this i am using axios interceptors my code is like
axios.interceptors.response.use(function (response) {
return response
}, function (error) {
// const { config, response: { status } } = error
const { config, response } = error
const originalRequest = config
if (response && response.status === 401) {
//notication or redirection
this.$vs.notify({
title: 'Error',
text: response.data['message'],
iconPack: 'feather',
icon: 'icon-check-circle',
color: 'danger'
})
}
return Promise.reject(error)
})
Now Question is that where i put this code in vue js so that it call after every request & so an error message shown & redirect to login once get 401 unauthorized..
Any Suggestion from anyone.
Thanks in advance!!
app.js or add them to separate file and include in app.js. There is post about this https://medium.com/#yaob/how-to-globally-use-axios-instance-and-interceptors-e28f351bb794
I have the following request to my laravel endpoint:
axios.get('http://localhost:8000/auth/login', {})
.then(function (response) {
console.log(response);
return {};
})
.catch(function (error) {
return {}
});
And my laravel endpoint set up as:
public function index() {
var_dump('login called.');die;
return response()->json(
[],
200
);
}
I Started my nextjs server (port 3000) and laravel server(8000), and when i browse to localhost:8000/auth/login in my browser I see "login called". however when I do that axios call, I get a status 200ok but no response data.
Request URL:http://localhost:8000/auth/login
Request Method:GET
Status Code:200 OK
Remote Address:127.0.0.1:8000
Referrer Policy:no-referrer-when-downgrade
Any idea what I am doing wrong?
Nothing is wrong with your code you are getting the response correctly, you see "login called" because you are accessing from a browser, therefore a browser has the cappability to render the html and you can see that.
But that axios call expects some json in return.
If you tweak the response a bit:
public function index() {
return response()->json(
['data' =>'Log in called'],
200
);
}
and if you twak axios response a bit
axios.get('http://localhost:8000/auth/login', {})
.then(function (response) {
console.log(response.data);
return {};
})
.catch(function (error) {
return {}
});
Inspect element open console and you will see 'Log in called'
I can not catch the error response with axios. How to do that?
I use something like:
axios
.post(...)
.then(response => {
console.log('Success: ', response)
}).catch(error => {
console.log('Error: ', error)
})
I see that the result of ajax request has 400 status code and the response body looks like {someField:["This field may not be blank"]} (Django backend). That's ok, I'm ready to process these errors in the catch handler.
But they go to the success handler instead. Why so? I see the following output in the console:
Success: Error: Request failed with status code 400
at createError (createError.js:16)
at settle (settle.js:18)
at XMLHttpRequest.handleLoad (xhr.js:77)
The success handler receives axios error object as the result. Why that may be and what to do next? This error object does not contain any usefull information.
UPD. Actually, the error object does contain the useful information, it contains the response object inside. So we can use:
axios
.post(...)
.then(response => {
if (response && response.response) {
console.log('This is also an error', response.response.status)
} else {
console.log('Success: ', response)
}
}).catch(error => {
console.log('Error: ', error)
})
But that looks super ugly.
The axios version is axios#0.16.2.
That's the big project, but I can not find any axios customizations.
Use Axios interceptors for the response. Check which status you want to force to fail as error so they go through the catch path whenever you receive said status code.
axios.interceptors.response.use(function (response) {
if (response.status === 400) {
return Promise.reject(response);
}
return response;
}, function (error) {
// Do something with response error
return Promise.reject(error);
});
If you are not receiving the expected status code, you might change the way you check the response in the interceptor. You can check any of the elements that Axios response is structured.
axios.interceptors.response.use(function (response) {
if (response.statusText !== 'OK') {
return Promise.reject(response);
}
return response;
}, function (error) {
// Do something with response error
return Promise.reject(error);
});
My token is currently being retrieved on the Laravel end. I used Postman to verify this.
I want to decrypt and store my token into local storage for a session with the user, but not sure how to go about this. I want to just put it in the login function which is currently doing the following:
$scope.login = function() {
$http.post('http://thesis-app.dev/login', $scope.user, {headers: {'X-
Requested-With': 'XMLHttpRequest'}}).success(function(response) {
console.log($scope.user);
})
.success(function(){
console.log("user logged in!");
console.log(response)
})
.error(function() {
console.log("their was an error");
console.log(response);
});
}
I am using React, React-Router and Superagent. I need authorization feature in my web application. Now, if the token is expired, I need the page redirect to login page.
I have put the ajax call functionality in a separated module and the token will be send on each request's header. In one of my component, I need fetch some data via ajax call, like below.
componentDidMount: function() {
api.getOne(this.props.params.id, function(err, data) {
if (err) {
this.setErrorMessage('System Error!');
} else if (this.isMounted()) {
this.setState({
user: data
});
}
}.bind(this));
},
If I got 401 (Unauthorized) error, maybe caused by token expired or no enough privilege, the page should be redirected to login page. Right now, in my api module, I have to use window.loication="#/login" I don't think this is a good idea.
var endCallback = function(cb, err, res) {
if (err && err.status == 401) {
return window.location('#/login');
}
if (res) {
cb(err, res.body);
} else {
cb(err);
}
};
get: function(cb) {
request
.get(BASE_URL + resources)
.end(endCallback.bind(null, cb));
},
But, I can't easily, call the react-router method in my api module. Is there an elegant way to implemented this easy feature? I don't want to add an error callback in every react components which need authorized.
I would try something like this:
Use the component's context to manipulate the router (this.context.router.transitionTo()).
Pass this method to the API callout as a param.
// component.js
,contextTypes: {
router: React.PropTypes.func
},
componentDidMount: function() {
api.getOne(this.props.params.id, this.context.router, function(err, data) {
if (err) {
this.setErrorMessage('System Error!');
} else if (this.isMounted()) {
this.setState({
user: data
});
}
}.bind(this));
},
// api.js
var endCallback = function(cb, router, err, res) {
if (err && err.status == 401) {
return router.transitionTo('login');
}
if (res) {
cb(err, res.body);
} else {
cb(err);
}
};
get: function(cb, router) {
request
.get(BASE_URL + resources)
.end(endCallback.bind(null, cb, router));
},
I know you didn't want a callback on each authenticated component, but I don't think there's any special react-router shortcuts to transition outside of the router.
The only other thing I could think of would be to spin up a brand new router on the error and manually send it to the login route. But I don't think that would necessarily work since it's outside of the initial render method.