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
JWTjust below theconst bcrypt = require("bcrypt");line at the top of theapp.jsfile like so:
const jwt = require("jsonwebtoken");
- Just below the
registerendpoint, 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
catchblock 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
catchblock 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
thenblock
.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
tokengenerated on a successful login
- If
emailis incorrect or does not exist
- If
passwordis 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