Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

res.redirect from an AJAX call

I'm trying to do a redirect after an ajax put request. I plan on using pure JS client side for validation.

Client:

$(document).ready(function() {
    login = () => {
        var username = $("[name='username']").val()
        var password = $("[name='password']").val()
        $.ajax({
            type: "put",
            url: '/login',
            data: {
                username: username,
                password: password
            }
            // success: function(response) {
            //  console.log('Success:')
            //  console.log(response.user)

            //  Cookies.set('username', response.user.username)
            //  Cookies.set('first_name', response.user.first_name)
            //  Cookies.set('last_name', response.user.last_name)
            //  Cookies.set('email', response.user.email)

            //  window.location.href = window.location.origin + '/'
            // },
            // error: function(error) {
            //  console.log("Error:")
            //  console.log(error)
            // }
        })
    }

    logout = () => {
        console.log("Log out clicked.")
        Cookies.remove('username')
        Cookies.remove('first_name')
        Cookies.remove('last_name')
        Cookies.remove('email')
        window.location.href = window.location.origin + '/logout'
    }
})

Server:

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('main')
});

router.put('/login', function(req, res) {
    // Password is not encrypted here
    console.log('req.body')
    console.log(req.body)

    User.findOne({ username: req.body.username }, function(err, user) {
        // Password is encrypted here
        if (err) throw err
        console.log('user')
        console.log(user)

        bcrypt.compare(req.body.password, user.password, function(err, result) {
            if (result) {
                var token = jwt.encode(user, JWT_SECRET)
                // return res.status(200).send({ user: user, token: token })
                return res.redirect('/')
            } else {
                return res.status(401).send({error: "Something is wrong."})
            }
        })
    })
})

I can't get main.hbs to render after a successful login. My commented code works, but I'm trying to do my redirect server side rather than client side because I'm told that it's better for security.

like image 478
Farid Avatar asked May 15 '17 03:05

Farid


People also ask

What does res redirect () function do?

The res. redirect() function lets you redirect the user to a different URL by sending an HTTP response with status 302. The HTTP client (browser, Axios, etc.) will then "follow" the redirect and send an HTTP request to the new URL as shown below.

Can ajax redirect to another page?

When the Button is clicked, jQuery AJAX call to the ASP.Net WebMethod is made and once the response is received in the Success event handler, the page is redirected to another page.

Does ajax follow redirect?

ajax appears to always follow redirects.

How do I redirect to another view in ajax success?

How do I redirect to another view in ajax success? $. ajax({ type: 'POST', url: 'AJAX URL', data: “YOUR DATA” // don't forget to pass your csrf_token when using post success: function(data){ $(“what_ever_you_want_to_replace”). html(data.


1 Answers

You should know when to use href and replace functionalities.

window.location.replace(...) will best way to represent an HTTP redirect.

Reason

When compared to window.location.href, window.location.replace(...) is better to use in a HTTP redirect scenario because replace() avoids keeping the originating page in the session history, this helps users to avoid get stuck in a never-ending back-button fiasco.

Summary

If you want to illustrate clicking on a link, use location.href

If you want to illustrate an HTTP redirect, use location.replace

Sample

//  an HTTP redirect
window.location.replace("http://example.com");

//  clicking on a link
window.location.href = "http://example.com";

Update

The server cannot do a redirect from an ajax request. In the end ajax involves the client (browser).

If you want, you can send the instruction of a redirection through the server side call, but it will be end up again on client side, in the callback. You can do that by returning an object from the server which contains the url you want to redirect to. Then use javascript to change the document's location property. Like Below:

Server Side Code

if (result) {
    var token = jwt.encode(user, JWT_SECRET)
    return res.status(200).send({result: 'redirect', url:'/'})
} else {
    return res.status(401).send({error: "Something is wrong."})
}

And then in Client Side Javascript:

$.ajax({
  type: "put",
  url: '/login',
  data: {
    username: username,
    password: password
  }
  success: function(response) {
    if (response.result == 'redirect') {
      //redirecting to main page from here.
      window.location.replace(response.url);
    }

  }
});

Apart from this your commented code is the correct way to do this. Just like one of the comments in you question "server side redirect is deadend for an ajax request as the instruction is not for the browser but some javascript handler."

like image 107
Keshan Nageswaran Avatar answered Oct 01 '22 03:10

Keshan Nageswaran