I'm having trouble getting redirects to work after accepting a post request from Axios. I do know that the request is being sent and that it at least gets some response from the '/' route, because my console logs "index", "user verified" which is what should happen when someone makes a get request to '/'. The problem is that the page doesn't load. I've even seen in the networking tab on google chrome that index.js is loaded but the page will not change no matter what I've tried! Is there any reason for this?
Other redirects that I've made do seem to work. For example, the index page will reroute to /login if the user is not logged in. This seems to only be an issue with the post request and I have tested it with and without passport authentication (obviously changed that you would need to be logged in to redirect) and it's the same result. So I do not think passport is causing the issue.
You can refer to package.json below to see what I am using
axios code:
axios.post('/login', {username: username, password: password})
/*.then(response => res.redirect('/'))*/
.then(function (response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
})
express side: I have console logs to alert myself during testing
server.get('/', (req,res) =>{
console.log("Index");
if (req.user){
console.log("user verified");
res.redirect('/');
app.render(req,res, '/',req.query);
} else {
console.log("user not logged in");
res.redirect('/login');
}
})
server.post('/login', passport.authenticate('local'), (req, res, next) => {
if (req.user) {
console.log("Logging in");
res.redirect('/');
} else {
console.log("Passwrod Incorrect");
return res.redirect('/login');
}
})
package.json
{
"name": "layout-component",
"version": "1.0.0",
"scripts": {
"dev": "node ./server.js",
"build": "next build",
"start": "NODE_ENV=production node ./server.js"
},
"dependencies": {
"@zeit/next-css": "^0.1.5",
"axios": "^0.18.0",
"bcryptjs": "^2.4.3",
"body-parser": "^1.18.2",
"connect-flash": "^0.1.1",
"connect-mongo": "^2.0.1",
"cookie-parser": "^1.4.3",
"express": "^4.16.3",
"express-session": "^1.15.6",
"express-validator": "^5.1.0",
"file-loader": "^1.1.11",
"hoist-non-react-statics": "^2.5.0",
"jsonwebtoken": "^8.2.0",
"mongodb": "^3.0.5",
"mongoose": "^5.0.12",
"next": "^5.1.0",
"passport": "^0.4.0",
"passport-local": "^1.0.0",
"prop-types": "^15.6.1",
"react": "^16.3.0",
"react-dom": "^16.3.0",
"semantic-ui-css": "^2.3.1",
"semantic-ui-react": "^0.79.0",
"url-loader": "^1.0.1"
},
"license": "ISC"
}
I figured this out after. Apparently, you cannot do a redirect from the server when you make an Axios post request. At least not the way that I was doing it (with the default Axios config.) You need to do the page change on the client side. Here's how I did it.
This really stumped me because I was receiving data from my redirect route using the other method but the page wasn't loading.
Also, for some reason using Next.js, the passport.js "successRedirect" and "failureRedirect" JSON doesn't seem to work. That's why I've written the routing the way I have and did not include those in the passport.authenticate() function. I hope this helps somebody!
My Axios submit function:
onSubmit = (e) => {
e.preventDefault()
const {username, password} = this.state;
axios.post('/login', {username: username, password: password})
.then(function (response) {
if (response.data.redirect == '/') {
window.location = "/index"
} else if (response.data.redirect == '/login'){
window.location = "/login"
}
})
.catch(function(error) {
window.location = "/login"
})
}
The post request in my Express server
server.post('/login', passport.authenticate('local'), (req, res, next) => {
if (req.user) {
var redir = { redirect: "/" };
return res.json(redir);
} else {
var redir = { redirect: '/login'};
return res.json(redir);
}
})
Although it won't be a server-side redirect, this can be accomplished cleanly on the client-side with Axios' "interceptor" which can intercept requests or responses before they get passed to then
/catch
:
// Add a request interceptor
axios.interceptors.request.use(function (config) {
// Do something before request is sent
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
// Add a response interceptor
axios.interceptors.response.use(function (response) {
// Do something with response data
return response;
}, function (error) {
// Do something with response error
return Promise.reject(error);
});
https://github.com/axios/axios#interceptors
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With