Sunday, 14 May 2017

Is user authentication better done with or without AJAX?

I’m experimenting with different methods of logging a user in on a site, and I don’t know which method is better in terms of performance and security.

In the first method, I'm using an ajax put request to my server. The server authenticates the user, and sends back the user's data, where the user is redirected to the home page (using window.location.href).

In the second method, I'm using a traditional HTML5 form to post the request directly to the server (no client side JS is used here as it is in the first method), and the server redirects to the user's /profile page after authenticating the user.

Code wise, here's Method 1:

login.hbs:

<button type="button" class="btn btn-success" onclick="login()">Login</button>

login.js:

$(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) {
                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) {
                alert("Error")
            }
        })
    }
})

server.js:

router.put('/login', function(req, res) {
    User.findOne({ username: req.body.username }, function(err, user) {
        if (err) throw err
        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 })
            } else {
                return res.status(401).send({error: "Something is wrong."})
            }
        })
    })
})
module.exports = router

Method 2:

login.hbs:

<form method="post" action="/login">
// ...
<button type="submit" class="btn btn-success">Login</button>

server.js:

router.post('/login', function(req, res) {
    User.findOne({ username: req.body.username }, function(err, user) {
        if (err) throw err
        bcrypt.compare(req.body.password, user.password, function(err, result) {
            if (result) {
                var token = jwt.encode(user, JWT_SECRET)
                return res.redirect('/profile/' + user.username)
            } else {
                return res.status(401).send({error: "Something is wrong."})
            }
        })
    })
})

router.get('/profile/:username', function(req, res, next) {
        User.findOne({ username: req.params.username }, function(err, user) {
            if (err) throw err
            else {
                res.render('profile', {
                    currentUser: user
                })
            }
        })
    });

Both methods seem to do the same thing (I've executed them both), except one of them uses client side JS. Would one of these methods be more ideal than the other?



via Farid

No comments:

Post a Comment