This will be the final part of this authentication series with Nodejs and mongoDB. Please checkout the previous article to catch up quickly.
In this tutorial, we will be looking at protecting some routes until a user is authenticated (logged in). Stick with me.
Starter project
The starter project for this tutorial can be gotten here
- Open your terminal and run
git clone --branch login-endpoint https://github.com/EBEREGIT/auth-backend
. - Navigate into the folder
cd auth-backend
. - Run
npm install
. - Run
nodemon index
. This starts up the server
Create 2 endpoints
We will need 2 endpoints in order to be able to show how authorization works. Copy the following endpoints and paste into the app.js
file just before the last line.
// free endpoint
app.get("/free-endpoint", (request, response) => {
response.json({ message: "You are free to access me anytime" });
});
// authentication endpoint
app.get("/auth-endpoint", (request, response) => {
response.json({ message: "You are authorized to access me" });
});
Feel free to check if the endpoints are working on postman or a browser
Create the authentication function
Here, we are creating a function that will enable us protect a particular endpoint until the user is authenticated.
Create a file in the root directory and name it
auth.js
Import
jasonwebtoken
at the top of the file
const jwt = require("jsonwebtoken");
- Create and export an asynchronous function in which our authorization code will live
module.exports = async (request, response, next) => {
}
- In the function, we will use a
try...catch...
block to check if a user is logged in.
try {
} catch (error) {
response.status(401).json({
error: new Error("Invalid request!"),
});
}
- In the
try{}
block, let's get the authentication token from theauthorization header
// get the token from the authorization header
const token = await request.headers.authorization.split(" ")[1];
- Next, let's check if the token that was generated matches the token string (RANDOM-TOKEN) we entered initially
//check if the token matches the supposed origin
const decodedToken = await jwt.verify(
token,
"RANDOM-TOKEN"
);
- Next, pass in the details of the
decodedToken
touser
constant
// retrieve the user details of the logged in user
const user = await decodedToken;
- Pass the
user
to the endpoint like so:
// pass the the user down to the endpoints here
request.user = user;
Finally, open the way to the endpoint like so:
// pass down functionality to the endpoint
next();
Our
auth.js
file now looks like this:
const jwt = require("jsonwebtoken");
module.exports = async (request, response, next) => {
try {
// get the token from the authorization header
const token = await request.headers.authorization.split(" ")[1];
//check if the token matches the supposed origin
const decodedToken = await jwt.verify(token, "RANDOM-TOKEN");
// retrieve the user details of the logged in user
const user = await decodedToken;
// pass the the user down to the endpoints here
request.user = user;
// pass down functionality to the endpoint
next();
} catch (error) {
response.status(401).json({
error: new Error("Invalid request!"),
});
}
};
Protecting the endpoint
This is the final and simplest step. We will start by importing the authentication function to the app.js
file like so:
const auth = require("./auth");
Now go to the authentication endpoint in the app.js
file and add auth
as a second argument like so
// authentication endpoint
app.get("/auth-endpoint", auth, (request, response) => {
response.json({ message: "You are authorized to access me" });
});
And that is it. That is all we need to protect that route. Let's test it out
Testing
If the user is not logged in
If the user is logged in
- Login Like so:
Copy the token
Open a new tab on
postman
Select
bearer token
in the authentication typePaste the token in the
token
field and send the request
CORS
One last thing!
We need to handle CORS error. This will allow the user in the frontend to consume the APIs that we have created without any problem.
To do this navigate to the
app.js
fileAdd the following code just below the
dbConnect()
line
// Curb Cores Error by adding a header here
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content, Accept, Content-Type, Authorization"
);
res.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, PATCH, OPTIONS"
);
next();
});
And with this, you are a nodejs authentication champion!!!
Conclusion
This part concludes this series on authentication with nodejs and mongoDB. We have seen how to create a registration and login endpoint, how to create protection on the endpoints if we deem fit.
All codes are found here
Next, we will be looking at how to host this app on heroku. See you soon
Top comments (7)
Thank you so much for this tutorial.
You are welcome 🤗
Thank you for reading 😊
Thanks a lot for this toturial.
It's really easy to understand and based on this, I can extend this into my own projects.
Thank you.
You are welcome 🤗
thanks a lot brother..... you made it so easy
Excellent Njoku! Thank you man
You are welcome.
I am happy you found it helpful