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