Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making redirects after an axios post request with express

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"
}
like image 358
asdfghjklm Avatar asked Apr 01 '18 19:04

asdfghjklm


2 Answers

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);
  }
})
like image 55
asdfghjklm Avatar answered Nov 19 '22 19:11

asdfghjklm


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

like image 31
docta_faustus Avatar answered Nov 19 '22 19:11

docta_faustus