How to Initialize Multilayer Node.js RESTful API with JWT Auth and PostgreSQL in 3 Steps
Tags: node, restfulapi, jwt, postgres
Published: 2018-03-13 11:53:19

---
title: How to Initialize Multilayer Node.js RESTful API with JWT Auth and PostgreSQL in 3 Steps
published: true
description: Layered architecture offers increased flexibility, maintainability and scalability, plus it’s easier to write, test and maintain. How can you implement it? If you are new to Node.js and RESTful API, we’ve written a how-to guide that will help you create a RESTful API that can be developed into a large service.
tags: node.js, RESTful API, JWT, PostgreSQL
---
<p name="e7a1" id="e7a1" class="graf graf--p graf-after--p">It’s a little-known fact that when Julius Caesar delivered his famous quote “Divide and conquer,” he was actually talking about using layered architecture for building web applications. Its principle lies in separating the user interface from the business logic and the business logic from the data access logic. Layered architecture offers increased flexibility, maintainability and scalability, plus it’s easier to write, test and maintain. Sounds good but how can you implement it using modern technologies?</p><p name="c1fe" id="c1fe" class="graf graf--p graf-after--p">For those of you who are new to Node.js and RESTful API, we’ve written a how-to guide that will help you create a RESTful API that can be developed into a large service. In this tutorial, we’ll show you how to start building a RESTful API in three steps. The JSON Web Token technique will help us handle authentication and PostgreSQL will be our database.</p><p name="7380" id="7380" class="graf graf--p graf-after--p">So, our steps to writing a RESTful API are:</p><ol class="postList"><li name="f997" id="f997" class="graf graf--li graf-after--p">Initializing a Node.js project</li><li name="3923" id="3923" class="graf graf--li graf-after--li">JWT authentication</li><li name="4315" id="4315" class="graf graf--li graf-after--li">Adding layers</li></ol><h3 name="0211" id="0211" class="graf graf--h3 graf-after--li">Initializing a Node.js project</h3><p name="9ef6" id="9ef6" class="graf graf--p graf-after--h3">Let’s start building our application. Create an empty folder and initialize a new project with the following command:npm init</p><p name="182d" id="182d" class="graf graf--p graf-after--p">To install the necessary packages, run the command:npm i bcrypt bluebird body-parser express http jsonwebtoken lodash pg sequelize sequelize-values — save</p><p name="88c5" id="88c5" class="graf graf--p graf-after--p">Next, create the following files in the main folder:</p><ul class="postList"><li name="4b4b" id="4b4b" class="graf graf--li graf-after--p"><strong class="markup--strong markup--li-strong">config.js</strong> (the application’s configuration like database connections, password salts, etc.)</li><li name="fecb" id="fecb" class="graf graf--li graf-after--li"><strong class="markup--strong markup--li-strong">db.js</strong> (responsible for the database connection)</li><li name="612d" id="612d" class="graf graf--li graf-after--li"><strong class="markup--strong markup--li-strong">router.js</strong> (handles http requests and dispatches them to controllers)</li><li name="84a3" id="84a3" class="graf graf--li graf-after--li"><strong class="markup--strong markup--li-strong">index.js</strong> — (a startup file)</li></ul><figure name="9a08" id="9a08" class="graf graf--figure graf-after--li"><div class="aspectRatioPlaceholder is-locked" style="max-width: 200px; max-height: 203px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 101.49999999999999%;"></div><div class="progressiveMedia js-progressiveMedia graf-image" data-image-id="0*j03M1BM5BkOMP91K." data-width="200" data-height="203"><img src="https://cdn-images-1.medium.com/freeze/max/38/0*j03M1BM5BkOMP91K.?q=20" crossorigin="anonymous" class="progressiveMedia-thumbnail js-progressiveMedia-thumbnail"><canvas class="progressiveMedia-canvas js-progressiveMedia-canvas"></canvas><img class="progressiveMedia-image js-progressiveMedia-image" data-src="https://cdn-images-1.medium.com/max/1000/0*j03M1BM5BkOMP91K."><noscript class="js-progressiveMedia-inner"><img class="progressiveMedia-noscript js-progressiveMedia-inner" src="https://cdn-images-1.medium.com/max/1000/0*j03M1BM5BkOMP91K."></noscript></div></div></figure><p name="b811" id="b811" class="graf graf--p graf-after--figure">Here’s the code our files contain:</p><h4 name="0223" id="0223" class="graf graf--h4 graf-after--p">config.js:</h4><pre name="2b1d" id="2b1d" class="graf graf--pre graf-after--h4">module.exports = {<br>     port: 3000,<br>     dbConnectionString: &#39;your postgresql connection&#39;,<br>     saltRounds: 2,<br>     jwtSecret: &#39;yo-its-a-secret&#39;,<br>     tokenExpireTime: &#39;6h&#39;<br>}</pre><h4 name="5390" id="5390" class="graf graf--h4 graf-after--pre">db.js:</h4><pre name="aa46" id="aa46" class="graf graf--pre graf-after--h4"><code class="markup--code markup--pre-code">const config = require(&#39;./config&#39;);<br>const Sequelize = require(&#39;sequelize&#39;);<br>var sequelize = new Sequelize(config.dbConnectionString);<br>require(&#39;sequelize-values&#39;)(sequelize);</code></pre><pre name="b639" id="b639" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">module.exports = sequelize;</code></pre><h4 name="74a8" id="74a8" class="graf graf--h4 graf-after--pre">router.js:</h4><pre name="8e3d" id="8e3d" class="graf graf--pre graf-after--h4"><code class="markup--code markup--pre-code">module.exports.set = app =&gt; {<br>     //endpoints will be here soon<br>}</code></pre><h4 name="884a" id="884a" class="graf graf--h4 graf-after--pre">index.js:</h4><pre name="2919" id="2919" class="graf graf--pre graf-after--h4"><code class="markup--code markup--pre-code">const express = require(&#39;express&#39;);<br>const http = require(&#39;http&#39;);<br>const bodyParser = require(&#39;body-parser&#39;);<br>const app = express();<br>const config = require(&#39;./config&#39;);<br>const router = require(&#39;./router&#39;);</code></pre><pre name="948e" id="948e" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">app.use(bodyParser.json());<br>app.use(bodyParser.urlencoded({<br>     extended: true<br>}));<br>app.use(express.static(&#39;client&#39;));<br>router.set(app);</code></pre><pre name="ca90" id="ca90" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">app.listen(config.port, () =&gt; console.log(&#39;App listening on port &#39;+ config.port));</code></pre><p name="cc6d" id="cc6d" class="graf graf--p graf-after--pre">After you’ve finished creating the files in the main folder, you have to define data models. To do this, create a folder models with the file <strong class="markup--strong markup--p-strong">index.js</strong> inside. Like this:</p><h4 name="7126" id="7126" class="graf graf--h4 graf-after--p">/models/index.js:</h4><pre name="77ef" id="77ef" class="graf graf--pre graf-after--h4"><code class="markup--code markup--pre-code">const Sequelize = require(&#39;sequelize&#39;);<br>const sequelize = require(&#39;../db&#39;);</code></pre><pre name="901a" id="901a" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">const User = sequelize.define(&#39;user&#39;, {<br>    login: Sequelize.STRING,<br>    password: Sequelize.STRING,<br>});</code></pre><pre name="ffdc" id="ffdc" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">const Order = sequelize.define(&#39;order&#39;, {<br>     title: Sequelize.STRING,<br>     date: {<br>         type: Sequelize.DATE,<br>         defaultValue: Sequelize.NOW<br>      },<br>     user_id: {<br>         type: Sequelize.INTEGER,<br>         references: {<br>              model: User,<br>              key: &#39;id&#39;<br>          }<br>      }<br> });</code></pre><pre name="ccc6" id="ccc6" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">User.hasMany(Order, {foreignKey: &#39;user_id&#39;});</code></pre><pre name="ff18" id="ff18" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">module.exports = {<br>     User,<br>     Order<br> }</code></pre><p name="9418" id="9418" class="graf graf--p graf-after--pre">This is how you start your multilayer Node.js project. At this point we have an entry point into our application (<strong class="markup--strong markup--p-strong">index.js</strong>), two DB models (<strong class="markup--strong markup--p-strong">models/index.js</strong>) and some basic configuration.</p><h3 name="f4ce" id="f4ce" class="graf graf--h3 graf-after--p">JWT Authentication</h3><p name="d70a" id="d70a" class="graf graf--p graf-after--h3">Before writing an actual API, let’s add authentication to our application. Create a services folder with files <strong class="markup--strong markup--p-strong">user.js</strong>and <strong class="markup--strong markup--p-strong">auth.js</strong> inside. Like this:</p><h4 name="4077" id="4077" class="graf graf--h4 graf-after--p">/services/index.js</h4><pre name="ad81" id="ad81" class="graf graf--pre graf-after--h4"><code class="markup--code markup--pre-code">const sequelize = require(&#39;../db&#39;);<br>const Users = require(&#39;../models&#39;).User;</code></pre><pre name="c40b" id="c40b" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">const addUser = user =&gt; Users.create(user);</code></pre><pre name="0a6c" id="0a6c" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">const getUserByLogin = login =&gt; Users.findOne({where: {login}});</code></pre><pre name="7817" id="7817" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">module.exports = {<br>    addUser,<br>    getUserByLogin<br>}</code></pre><p name="e231" id="e231" class="graf graf--p graf-after--pre">Once a user is logged-in, each subsequent request will include a token (JWT), allowing the user to access routes, services and resources according to the permissions stored in the token.</p><h4 name="329f" id="329f" class="graf graf--h4 graf-after--p">/services/auth.js will handle JWT authentication:</h4><pre name="2b80" id="2b80" class="graf graf--pre graf-after--h4"><code class="markup--code markup--pre-code">const bcrypt = require(&#39;bcrypt&#39;);<br>const jwt = require(&#39;jsonwebtoken&#39;);</code></pre><pre name="83ff" id="83ff" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">const Users = require(&#39;../models&#39;).User;<br>const config =  require(&#39;../config&#39;);</code></pre><pre name="339c" id="339c" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">const authenticate = params =&gt; {<br>      return Users.findOne({<br>          where: {<br>              login: params.login<br>          },<br>          raw: true<br>     }).then(user =&gt; {<br>          if (!user)<br>              throw new Error(&#39;Authentication failed. User not found.&#39;);<br>          if (!bcrypt.compareSync(params.password || &#39;&#39;, user.password))<br>              throw new Error(&#39;Authentication failed. Wrong password.&#39;);<br>          const payload = {<br>              login: user.login,<br>              id: user.id,<br>              time: new Date()<br>          };</code></pre><pre name="973d" id="973d" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">          var token = jwt.sign(payload, config.jwtSecret, {<br>              expiresIn: config.tokenExpireTime<br>          });<br>          return token;<br>      });<br>}</code></pre><pre name="8d47" id="8d47" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code"><br>module.exports = {<br>    authenticate<br>}</code></pre><p name="49b9" id="49b9" class="graf graf--p graf-after--pre">To handle requests for registration and authentication, our application should have a controller.</p><p name="9730" id="9730" class="graf graf--p graf-after--p">Let’s create a file <strong class="markup--strong markup--p-strong">auth.js</strong> and place it in the controllers folder.</p><h4 name="e6a0" id="e6a0" class="graf graf--h4 graf-after--p">/controllers/auth.js:</h4><pre name="30e2" id="30e2" class="graf graf--pre graf-after--h4"><code class="markup--code markup--pre-code">const config =  require(&#39;../config&#39;);<br>const jwt = require(&#39;jsonwebtoken&#39;);<br>const bcrypt = require(&#39;bcrypt&#39;);</code></pre><pre name="b145" id="b145" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">const authService = require(&#39;../services/auth&#39;);<br>const userService = require(&#39;../services/user&#39;);</code></pre><pre name="c2ae" id="c2ae" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">function login(req, res){<br>     return authService.authenticate(req.body)<br>     .then(token =&gt; {<br>          res.send({<br>               success: true,<br>               data: { token }<br>          });<br>     })<br>     .catch(err =&gt; {<br>          res.send({<br>               success: false,<br>               message: err.message //not the best error handling.<br>               //for better error handling visit github repository, link provided below<br>          });<br>     })<br>};</code></pre><pre name="f12b" id="f12b" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">function register(req, res){<br>     var login = req.body.login;<br>     return userService.getUserByLogin(req.body.login || &#39;&#39;)<br>     .then(exists =&gt; {</code></pre><pre name="f9e1" id="f9e1" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">          if (exists){<br>               return res.send({<br>                   success: false,<br>                   message: &#39;Registration failed. User with this email already registered.&#39;<br>               });<br>          }</code></pre><pre name="3f2b" id="3f2b" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">          var user = {<br>               login: req.body.login,<br>               password: bcrypt.hashSync(req.body.password, config.saltRounds)<br>           }</code></pre><pre name="8e22" id="8e22" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">          return userService.addUser(user)<br>          .then(() =&gt; res.send({success: true}));<br>     });<br>};</code></pre><pre name="dd54" id="dd54" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">module.exports = {<br>    login,<br>    register<br>}</code></pre><p name="9ebf" id="9ebf" class="graf graf--p graf-after--pre">After this, we need to add endpoints to our API.</p><h4 name="5fcc" id="5fcc" class="graf graf--h4 graf-after--p">You can do it in the router.js file:</h4><pre name="bcd1" id="bcd1" class="graf graf--pre graf-after--h4"><code class="markup--code markup--pre-code">const authController = require(&#39;./controllers/auth&#39;);</code></pre><pre name="997f" id="997f" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">module.exports.set = app =&gt; {<br>    app.post(&#39;/login&#39;, authController.login);<br>    app.post(&#39;/register&#39;, authController.register);<br>}</code></pre><p name="40bd" id="40bd" class="graf graf--p graf-after--pre">Let’s start the server by running the command node <strong class="markup--strong markup--p-strong">index.js </strong>and test the login and register functionality.</p><figure name="3709" id="3709" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 385px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 54.900000000000006%;"></div><div class="progressiveMedia js-progressiveMedia graf-image" data-image-id="0*8XcQdWO2Gw4eqsFT." data-width="750" data-height="412" data-action="zoom" data-action-value="0*8XcQdWO2Gw4eqsFT."><img src="https://cdn-images-1.medium.com/freeze/max/38/0*8XcQdWO2Gw4eqsFT.?q=20" crossorigin="anonymous" class="progressiveMedia-thumbnail js-progressiveMedia-thumbnail"><canvas class="progressiveMedia-canvas js-progressiveMedia-canvas"></canvas><img class="progressiveMedia-image js-progressiveMedia-image" data-src="https://cdn-images-1.medium.com/max/1000/0*8XcQdWO2Gw4eqsFT."><noscript class="js-progressiveMedia-inner"><img class="progressiveMedia-noscript js-progressiveMedia-inner" src="https://cdn-images-1.medium.com/max/1000/0*8XcQdWO2Gw4eqsFT."></noscript></div></div></figure><figure name="a0f9" id="a0f9" class="graf graf--figure graf-after--figure"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 457px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 65.3%;"></div><div class="progressiveMedia js-progressiveMedia graf-image" data-image-id="0*MVTMd2V14lsPQ43D." data-width="750" data-height="490" data-action="zoom" data-action-value="0*MVTMd2V14lsPQ43D."><img src="https://cdn-images-1.medium.com/freeze/max/38/0*MVTMd2V14lsPQ43D.?q=20" crossorigin="anonymous" class="progressiveMedia-thumbnail js-progressiveMedia-thumbnail"><canvas class="progressiveMedia-canvas js-progressiveMedia-canvas"></canvas><img class="progressiveMedia-image js-progressiveMedia-image" data-src="https://cdn-images-1.medium.com/max/1000/0*MVTMd2V14lsPQ43D."><noscript class="js-progressiveMedia-inner"><img class="progressiveMedia-noscript js-progressiveMedia-inner" src="https://cdn-images-1.medium.com/max/1000/0*MVTMd2V14lsPQ43D."></noscript></div></div></figure><h3 name="1605" id="1605" class="graf graf--h3 graf-after--figure">Adding Layers</h3><p name="89d9" id="89d9" class="graf graf--p graf-after--h3">Now we have the Controller layer and the Data Access layer in our application. To link them together, we need the Service layer in between. Using layers is a good way to ensure separation of responsibilities, which allows making data, business logic and presentation code independent. The Presentational layer (user) interacts with the Controllers layer (API) that uses the Service layer (business rules) to access and modify data via the Data Access layer.</p><p name="21ee" id="21ee" class="graf graf--p graf-after--p">So, let’s start with our first service for the order model.</p><h4 name="1c9d" id="1c9d" class="graf graf--h4 graf-after--p">Create a file services/order.js</h4><pre name="7b31" id="7b31" class="graf graf--pre graf-after--h4"><code class="markup--code markup--pre-code">const Orders = require(&#39;../models&#39;).Order;</code></pre><pre name="afe8" id="afe8" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">const getAll = () =&gt; Orders.findAll();</code></pre><pre name="fbbe" id="fbbe" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">const getById = id =&gt; Orders.findById(id);</code></pre><pre name="dca6" id="dca6" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">const add = order =&gt; Orders.create(order);</code></pre><pre name="f5be" id="f5be" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">module.exports = {add, getAll, getById};</code></pre><p name="8098" id="8098" class="graf graf--p graf-after--pre">Now, we can create a controller to work with that service.</p><h4 name="6d13" id="6d13" class="graf graf--h4 graf-after--p">controllers/order.js</h4><pre name="9208" id="9208" class="graf graf--pre graf-after--h4"><code class="markup--code markup--pre-code">const orderService = require(&#39;../services/order&#39;);</code></pre><pre name="827b" id="827b" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">function getOrders(req, res){<br>    orderService.getAll()<br>    .then(data =&gt; res.send(data));<br>};</code></pre><pre name="0351" id="0351" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">function getOrder(req, res){<br>    orderService.getById(req.params.id)<br>    .then(data =&gt; res.send(data));<br>}</code></pre><pre name="804e" id="804e" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">function addOrder(req, res){<br>    orderService.add({<br>        title: req.body.title,<br>        user_id: 1<br>    })<br>    .then(data =&gt; res.send(data));<br>};</code></pre><pre name="22f6" id="22f6" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">module.exports = {<br>    getOrders,<br>    getOrder,<br>    addOrder<br>}</code></pre><h4 name="f14b" id="f14b" class="graf graf--h4 graf-after--pre">And one more thing we need to finish our orders part of RESTful API is to add endpoints to router.js:</h4><pre name="40cd" id="40cd" class="graf graf--pre graf-after--h4"><code class="markup--code markup--pre-code">const orderController = require(&#39;./controllers/order&#39;);<br>…<br>   app.get(&#39;/orders&#39;, orderController.getOrders);<br>   app.get(&#39;/orders/:id&#39;, orderController.getOrder);<br>   app.post(&#39;/orders&#39;, orderController.addOrder);</code></pre><p name="d768" id="d768" class="graf graf--p graf-after--pre">Here’s some testing illustration of a working API:</p><figure name="bb84" id="bb84" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 308px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 44%;"></div><div class="progressiveMedia js-progressiveMedia graf-image" data-image-id="0*UX2SARvacaowtBZJ." data-width="750" data-height="330" data-action="zoom" data-action-value="0*UX2SARvacaowtBZJ."><img src="https://cdn-images-1.medium.com/freeze/max/38/0*UX2SARvacaowtBZJ.?q=20" crossorigin="anonymous" class="progressiveMedia-thumbnail js-progressiveMedia-thumbnail"><canvas class="progressiveMedia-canvas js-progressiveMedia-canvas"></canvas><img class="progressiveMedia-image js-progressiveMedia-image" data-src="https://cdn-images-1.medium.com/max/1000/0*UX2SARvacaowtBZJ."><noscript class="js-progressiveMedia-inner"><img class="progressiveMedia-noscript js-progressiveMedia-inner" src="https://cdn-images-1.medium.com/max/1000/0*UX2SARvacaowtBZJ."></noscript></div></div></figure><figure name="e83a" id="e83a" class="graf graf--figure graf-after--figure"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 412px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 58.8%;"></div><div class="progressiveMedia js-progressiveMedia graf-image" data-image-id="0*57jT_t78_id0iF1e." data-width="750" data-height="441" data-action="zoom" data-action-value="0*57jT_t78_id0iF1e."><img src="https://cdn-images-1.medium.com/freeze/max/38/0*57jT_t78_id0iF1e.?q=20" crossorigin="anonymous" class="progressiveMedia-thumbnail js-progressiveMedia-thumbnail"><canvas class="progressiveMedia-canvas js-progressiveMedia-canvas"></canvas><img class="progressiveMedia-image js-progressiveMedia-image" data-src="https://cdn-images-1.medium.com/max/1000/0*57jT_t78_id0iF1e."><noscript class="js-progressiveMedia-inner"><img class="progressiveMedia-noscript js-progressiveMedia-inner" src="https://cdn-images-1.medium.com/max/1000/0*57jT_t78_id0iF1e."></noscript></div></div></figure><figure name="177b" id="177b" class="graf graf--figure graf-after--figure"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 357px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 50.9%;"></div><div class="progressiveMedia js-progressiveMedia graf-image" data-image-id="0*t59vn7ZhHzPWTvCg." data-width="750" data-height="382" data-action="zoom" data-action-value="0*t59vn7ZhHzPWTvCg."><img src="https://cdn-images-1.medium.com/freeze/max/38/0*t59vn7ZhHzPWTvCg.?q=20" crossorigin="anonymous" class="progressiveMedia-thumbnail js-progressiveMedia-thumbnail"><canvas class="progressiveMedia-canvas js-progressiveMedia-canvas"></canvas><img class="progressiveMedia-image js-progressiveMedia-image" data-src="https://cdn-images-1.medium.com/max/1000/0*t59vn7ZhHzPWTvCg."><noscript class="js-progressiveMedia-inner"><img class="progressiveMedia-noscript js-progressiveMedia-inner" src="https://cdn-images-1.medium.com/max/1000/0*t59vn7ZhHzPWTvCg."></noscript></div></div></figure><p name="d5c4" id="d5c4" class="graf graf--p graf-after--figure">The next thing we need is to allow access only to authenticated users. To do this, let’s add middleware that checks if the user is logged in:</p><h4 name="849e" id="849e" class="graf graf--h4 graf-after--p">middlewares/auth.js:</h4><pre name="9ea4" id="9ea4" class="graf graf--pre graf-after--h4"><code class="markup--code markup--pre-code">const jwt = require(&#39;jsonwebtoken&#39;);<br>const config =  require(&#39;../config&#39;);</code></pre><pre name="3cfc" id="3cfc" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">const checkAuth = (req, res, next) =&gt; {<br>    var token = req.headers[&#39;token&#39;];<br>    if (!token)<br>        return res.status(403).send({ auth: false, message: &#39;No token provided.&#39; });<br>    <br>    jwt.verify(token, config.jwtSecret, (err, decoded) =&gt; {<br>        if (err)<br>            return res.status(500).send({ auth: false, message: &#39;Failed to authenticate token.&#39; });</code></pre><pre name="4c4f" id="4c4f" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">    req.user = {<br>         login: decoded.login,<br>         id: decoded.id<br>    };</code></pre><pre name="b8ce" id="b8ce" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">    next();<br>    });<br>}</code></pre><pre name="d6f2" id="d6f2" class="graf graf--pre graf-after--pre"><code class="markup--code markup--pre-code">module.exports = {<br>    checkAuth<br>}</code></pre><p name="bcf4" id="bcf4" class="graf graf--p graf-after--pre">After this, the authentication middleware should be used as the middleware argument (the second one) in endpoints functions. Now, the user can’t access data without providing a valid authentication token.</p><pre name="27bb" id="27bb" class="graf graf--pre graf-after--p"><code class="markup--code markup--pre-code">app.get(&#39;/orders&#39;, authMiddleware.checkAuth, orderController.getOrders);<br>app.get(&#39;/orders/:id&#39;, authMiddleware.checkAuth, orderController.getOrder);<br>app.post(&#39;/orders&#39;, authMiddleware.checkAuth, orderController.addOrder);<br>app.get(&#39;/user_orders&#39;, authMiddleware.checkAuth, userController.getUsersWithOrders)</code></pre><p name="29c6" id="29c6" class="graf graf--p graf-after--pre">As you can see it works :)</p><figure name="984e" id="984e" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 262px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 37.5%;"></div><div class="progressiveMedia js-progressiveMedia graf-image" data-image-id="0*liSSB6AatlJftxbi." data-width="750" data-height="281" data-action="zoom" data-action-value="0*liSSB6AatlJftxbi."><img src="https://cdn-images-1.medium.com/freeze/max/38/0*liSSB6AatlJftxbi.?q=20" crossorigin="anonymous" class="progressiveMedia-thumbnail js-progressiveMedia-thumbnail"><canvas class="progressiveMedia-canvas js-progressiveMedia-canvas"></canvas><img class="progressiveMedia-image js-progressiveMedia-image" data-src="https://cdn-images-1.medium.com/max/1000/0*liSSB6AatlJftxbi."><noscript class="js-progressiveMedia-inner"><img class="progressiveMedia-noscript js-progressiveMedia-inner" src="https://cdn-images-1.medium.com/max/1000/0*liSSB6AatlJftxbi."></noscript></div></div></figure><h4 name="ef98" id="ef98" class="graf graf--h4 graf-after--figure">The final thing we need to do is define the addOrder function.</h4><pre name="a9ae" id="a9ae" class="graf graf--pre graf-after--h4"><code class="markup--code markup--pre-code">function addOrder(req, res){<br>    orderService.add({<br>         title: req.body.title,<br>         user_id: req.user.id<br>    })<br>    .then(data =&gt; res.send(data));<br>};</code></pre><p name="a8c8" id="a8c8" class="graf graf--p graf-after--pre">And that’s it! We’ve created a small app with RESTful API. According to the Multilayer Architecture concept, we have the Controllers layer, the Service layer and the Data Access layer. Our API with JWT authorization makes it easy to add the Presentational layer, e.g. web application or mobile application.</p><p name="6d2e" id="6d2e" class="graf graf--p graf-after--p graf--trailing">Feel free to check the code in the <a href="https://github.com/VitaliiKulyk/asap" data-href="https://github.com/VitaliiKulyk/asap" class="markup--anchor markup--p-anchor" rel="nofollow noopener" target="_blank"><strong class="markup--strong markup--p-strong">repository</strong></a>. Well, don’t just stand there — go ahead and try it yourself. Good luck from <a href="https://www.eliftech.com/" data-href="https://www.eliftech.com/" class="markup--anchor markup--p-anchor" rel="nofollow noopener" target="_blank"><strong class="markup--strong markup--p-strong">ElifTech</strong></a>!</p></div></div></section></div>