DEV Community

Margaret W.N
Margaret W.N

Posted on

Password authentication

A user will typically input the email/username and password to log into a system. How do we verify the inputs and successfully retrieve their account?

I'm using mongoose findOne() inbuilt method, and passing in a condition to retrieve the User email similar to the email input from the request. I'm also passing an asynchronous error first callback function. If an error occurs during retrieval the function exists immediately. If the user is successfully retrieved the saved password and password input are compared using bcrypt.compare( ).

router.route('/users/login')
    .post((req, res) => {
      User.findOne({ email: req.body.email }, async (err, user) => {
        if (err) {
          return res.send(err);
        }
        if (await bcrypt.compare(req.body.password, user.password)) {
          return res.send(`Welcome back ${user.firstName}`)
        }
        return res.send('Wrong Password');
      })
    });
Enter fullscreen mode Exit fullscreen mode

bcrypt.compare( ) resolves to either true or false. If it results to true a welcome back message with the users first name will be sent back. If false we'll return wrong Password.

Lets Create a User
Alt Text

Output using the correct Password
Alt Text

Output using the wrong Password
Alt Text

Nothing beats a working solution!
Day 26

Top comments (4)

Collapse
 
dealloc profile image
Wannes Gennar

If the username does not exist, you still want to run a bcrypt compare.
The reason for this is that your requests will take on average the same time for an existing and a non-existing user, which prevents timing attacks (where the attacker can see if a username exists by simply timing the response times; the "slower" response times are where the backend is also doing password validation, and thus the username exists).

I learned about this myself when developing a backend in Elixir, I recommend reading the last bit of hexdocs.pm/comeonin/Comeonin.html#...

Collapse
 
mtee profile image
Margaret W.N

Intresting! I'll definitely read about that. Thank you for sharing the resource

Collapse
 
nathanbarrett profile image
Nathan Barrett

nice! looks great! i like how you went with the early returns inside of each if statement instead of doing if->else if->else. this is called the "Return Early" method and it is much preferred over "else" statements in most circumstances and you successfully implemented it! ( forum.freecodecamp.org/t/the-retur... ).
also, in the future you will also probably run into http status codes and how they help others that use the endpoints that you create ( httpstatuses.com/ ). so if you get the error you could also return res.status(500).send('there was an error') . and if the password doesn't match you could res.status(401).send('Wrong Password'). 200 is the main "all good" status code but anything in the 200s is considered a "good" response (or "accepted" may be a better word).

Collapse
 
mtee profile image
Margaret W.N

Thank you Nathan.

I'll go through the resources and familiarize myself with the http status codes.