This is the third part of this authentication series with nodejs and mongoDB. If you have not checked out the previous parts, please check out part 1 and part 2.
In this part of the tutorial, we will be covering the login with jasonwebtoken (JWT)
. By the end, we will have seen how to crosscheck users and match the hashed password
to the plain text password
.
Without wasting anytime, let's jump into it.
Starter Project
If you are not coming from the previous tutorial, then you can get the starter project from here
Login Endpoint
- Install JWT
npm i jsonwebtoken -s
- Import
JWT
just below theconst bcrypt = require("bcrypt");
line at the top of theapp.js
file like so:
const jwt = require("jsonwebtoken");
- Just below the
register
endpoint, enter the following function:
app.post("/login", (request, response) => {
})
- Let's check if the email the user enter on login exists with the following line of code:
User.findOne({ email: request.body.email })
Next, we will use a then...catch...
block to check if the email search above was successful or not
- If it is unsuccessful, we will capture that in the
catch
block like so:
User.findOne({ email: request.body.email })
.then()
.catch((e) => {
response.status(404).send({
message: "Email not found",
e,
});
});
- If successful, we will compare the password entered against the hashed password in our database. We are doing this in the
then...
block like so:
.then((user)=>{
bcrypt.compare(request.body.password, user.password)
})
We will then use a then...catch...
block again to check if the comparison is successful or not
- If the comparison is unsuccessful, we will return an error message in the
catch
block like so:
.then((user)=>{
bcrypt.compare(request.body.password, user.password)
.then()
.catch((error) => {
response.status(400).send({
message: "Passwords does not match",
error,
});
})
})
- Let's double check if the password is correct in the
then
block
.then((passwordCheck) => {
// check if password matches
if(!passwordCheck) {
return response.status(400).send({
message: "Passwords does not match",
error,
});
}
})
- If the password matches, then create a random token with the
jwt.sign()
function. It takes 3 parameters i.e.jwt.sign(payload, secretOrPrivateKey, [options, callback])
. You can read more here
bcrypt.compare(request.body.password, user.password)
.then((passwordCheck) => {
// check if password matches
if(!passwordCheck) {
return response.status(400).send({
message: "Passwords does not match",
error,
});
}
// create JWT token
const token = jwt.sign(
{
userId: user._id,
userEmail: user.email,
},
"RANDOM-TOKEN",
{ expiresIn: "24h" }
);
})
- Finally, return a success message with the token created
.then((user)=>{
bcrypt.compare(request.body.password, user.password)
.then((passwordCheck) => {
// check if password matches
if(!passwordCheck) {
return response.status(400).send({
message: "Passwords does not match",
error,
});
}
// create JWT token
const token = jwt.sign(
{
userId: user._id,
userEmail: user.email,
},
"RANDOM-TOKEN",
{ expiresIn: "24h" }
);
// return success response
response.status(200).send({
message: "Login Successful",
email: user.email,
token,
});
})
- Our Login Endpoint now looks like this:
// login endpoint
app.post("/login", (request, response) => {
// check if email exists
User.findOne({ email: request.body.email })
// if email exists
.then((user) => {
// compare the password entered and the hashed password found
bcrypt
.compare(request.body.password, user.password)
// if the passwords match
.then((passwordCheck) => {
// check if password matches
if(!passwordCheck) {
return response.status(400).send({
message: "Passwords does not match",
error,
});
}
// create JWT token
const token = jwt.sign(
{
userId: user._id,
userEmail: user.email,
},
"RANDOM-TOKEN",
{ expiresIn: "24h" }
);
// return success response
response.status(200).send({
message: "Login Successful",
email: user.email,
token,
});
})
// catch error if password do not match
.catch((error) => {
response.status(400).send({
message: "Passwords does not match",
error,
});
});
})
// catch error if email does not exist
.catch((e) => {
response.status(404).send({
message: "Email not found",
e,
});
});
});
Testing
- Let's try to login with the credentials we registered in the last tutorial. See the random
token
generated on a successful login
- If
email
is incorrect or does not exist
- If
password
is incorrect
At this point, you can put hands together for yourself because you have just conquered AUTHENTICATION
👏🏼👏🏼👏🏼👏🏼👏🏼
Conclusion
We began this authentication series by setting up out database in PART 1, we created a model for the user
collection and a register
endpoint in the PART 2 and finally, in this part, we have successfully created the login
endpoint checking if users exist or not.
Congratulations!!! 🍾🍾🍾
We will look into Protecting Endpoints from unauthenticated users next. I hope to catch you there.
Meanwhile, all codes are here
Top comments (4)
eiii please am not getting you ooo
I hope the call made things clearer.
It is important to pay attention to every detail. That is why I make the tutorial step by step. I also make indicators on the screenshots.
Please Follow these indicators
Where was the user data added to the database?
Please make things more clearer
I hope the call made things clearer.
It is important to pay attention to every detail. That is why I make the tutorial step by step. I also make indicators on the screenshots.
Please Follow these indicators