{"componentChunkName":"component---src-templates-blog-list-template-js","path":"/engineering/5","result":{"data":{"allMarkdownRemark":{"edges":[{"node":{"excerpt":"Introduction User authentication is the process of validating a user's identity to ensure that they are who they claim to be. Implementing…","fields":{"slug":"/engineering/guest-post/authenticating-flutter-apps/"},"html":"<h2 id=\"introduction\" style=\"position:relative;\"><a href=\"#introduction\" aria-label=\"introduction permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Introduction</h2>\n<p>User authentication is the process of validating a user's identity to ensure that they are who they claim to be. Implementing user authentication in your application is critical to prevent unauthorized users from accessing sensitive information.</p>\n<p>This tutorial focuses on implementing user authentication and registration in Flutter applications using the LoginRadius API.</p>\n<h2 id=\"prerequisites\" style=\"position:relative;\"><a href=\"#prerequisites\" aria-label=\"prerequisites permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Prerequisites</h2>\n<p>If you wish to follow along with this tutorial, you must have the following set up:</p>\n<ul>\n<li><a href=\"https://accounts.loginradius.com/auth.aspx\">Sign up for a free LoginRadius developer account</a></li>\n<li>Any IDE that has <a href=\"https://docs.flutter.dev/get-started/install\">Flutter SDK</a> installed (i.e., <a href=\"https://developer.android.com/studio\">Android Studio</a>, <a href=\"https://code.visualstudio.com/\">VSCode</a>)</li>\n<li>A basic understanding of <a href=\"https://dart.dev/\">Dart</a> and <a href=\"https://flutter.dev/\">Flutter</a></li>\n</ul>\n<p>This tutorial is verified with Flutter v2.5.1 and Android Studio v3.5.</p>\n<h2 id=\"getting-started-with-loginradius\" style=\"position:relative;\"><a href=\"#getting-started-with-loginradius\" aria-label=\"getting started with loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Getting Started with LoginRadius</h2>\n<h3 id=\"what-is-loginradius\" style=\"position:relative;\"><a href=\"#what-is-loginradius\" aria-label=\"what is loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is LoginRadius?</h3>\n<p>LoginRadius is a cloud-based, SaaS Customer Identity and Access Management (CIAM) platform that provides developers and businesses simplified and robust features for managing customer identity, privacy, and access. LoginRadius offers high-level, secure, and well-documented APIs for integrating User Authentication and Single Sign-on (SSO) into your application.</p>\n<h3 id=\"why-use-loginradius\" style=\"position:relative;\"><a href=\"#why-use-loginradius\" aria-label=\"why use loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Why use LoginRadius?</h3>\n<p>LoginRadius offers:</p>\n<ul>\n<li>A scalable infrastructure</li>\n<li>Built-in security measures to improve user account security and safe user data management</li>\n<li>Advanced login options such as Social SSO and Passwordless Login to improve the user experience</li>\n<li>SDKs and well-documented APIs for seamless integration into your application</li>\n</ul>\n<p>So, with everything out of the way, let's get started.</p>\n<h2 id=\"setting-up-loginradius-for-your-application\" style=\"position:relative;\"><a href=\"#setting-up-loginradius-for-your-application\" aria-label=\"setting up loginradius for your application permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Setting Up LoginRadius for Your Application</h2>\n<p>After creating an account with LoginRadius, it sets up a free app for you. This is the app in which you would integrate the LoginRadius API with Flutter. Here my app name is “tayy”.</p>\n<p><img src=\"/0d7ac3f6bd1f6f3ad31570d5b79c1ebd/app_window.webp\" alt=\"LoginRadius App Screen\"></p>\n<p>Next, you need to obtain your LoginRadius API credentials. To do so, login to your Dashboard and navigate to the <code>Configuration</code> tab in the sidebar menu. You will find your API credentials under the <code>API Key and Secret</code> section. Copy and store your <strong>APP Name</strong>, <strong>API Key</strong>, and <strong>API Secret</strong> somewhere safe and easily accessible.</p>\n<p><img src=\"/8a552a2950ebab3006e383386c6a11ef/configuration_tab.webp\" alt=\"LoginRadius Configuration Tab\"></p>\n<h2 id=\"integrating-loginradius-api-with-your-flutter-application\" style=\"position:relative;\"><a href=\"#integrating-loginradius-api-with-your-flutter-application\" aria-label=\"integrating loginradius api with your flutter application permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Integrating LoginRadius API with Your Flutter Application.</h2>\n<h3 id=\"step-1-create-a-new-flutter-project\" style=\"position:relative;\"><a href=\"#step-1-create-a-new-flutter-project\" aria-label=\"step 1 create a new flutter project permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 1: Create a New Flutter project</h3>\n<p>Create a new Flutter project and navigate to the folder of the application by running the following commands in your terminal:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"dart\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">flutter create loginradius_example</span>\n<span class=\"grvsc-line\">cd loginradius_example</span></code></pre>\n<h3 id=\"step-2-install-dependencies\" style=\"position:relative;\"><a href=\"#step-2-install-dependencies\" aria-label=\"step 2 install dependencies permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 2: Install Dependencies</h3>\n<p>Next, you need to install the <code>dio</code> package as a dependency in our project. The <code>dio</code> package is a powerful HTTP client used for making network requests.</p>\n<p>Run the following command to get the newest version of the <code>dio</code> package in your project.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">flutter pub add dio</span></code></pre>\n<p>Then, install the dependency by running <code>flutter pub get</code> in your terminal.</p>\n<h3 id=\"project-structure\" style=\"position:relative;\"><a href=\"#project-structure\" aria-label=\"project structure permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Project Structure</h3>\n<p>The project is being structured in this order:</p>\n<p><img src=\"/cb6ed60c36b1e957eec023d28a260df7/folder-structure.webp\" alt=\"Folder Structure\"></p>\n<ul>\n<li>Core (contains a class that handles network requests)</li>\n<li>Screens (the UI of our app)</li>\n<li>Utils (helper components)</li>\n</ul>\n<h3 id=\"step-3-setting-up-the-api-client-class\" style=\"position:relative;\"><a href=\"#step-3-setting-up-the-api-client-class\" aria-label=\"step 3 setting up the api client class permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 3: Setting up the API Client Class</h3>\n<p>Create a new dart file named <code>api_client.dart</code> and import the <code>dio</code> package into the file, as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"dart\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">import &#39;package:dio/dio.dart&#39;;</span></code></pre>\n<p>Now let’s create a class named <code>ApiClient</code> and initialize the <code>Dio</code> object in it. The <code>ApiClient</code> class will contain several methods for making network requests based on your features, including User Registration, User Login, Get User Profile Data, and User Logout.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"dart\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">import &#39;package:dio/dio.dart&#39;;</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">class ApiClient {</span>\n<span class=\"grvsc-line\">   final Dio _dio = Dio();</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">    Future&lt;Response&gt; registerUser() async {</span>\n<span class=\"grvsc-line\">        //IMPLEMENT USER REGISTRATION</span>\n<span class=\"grvsc-line\">    }</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">    Future&lt;Response&gt; login() async {</span>\n<span class=\"grvsc-line\">        //IMPLEMENT USER LOGIN</span>\n<span class=\"grvsc-line\">    }</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">    Future&lt;Response&gt; getUserProfileData() async {</span>\n<span class=\"grvsc-line\">        //GET USER PROFILE DATA</span>\n<span class=\"grvsc-line\">    }</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">    Future&lt;Response&gt; logout() async {</span>\n<span class=\"grvsc-line\">        //IMPLEMENT USER LOGOUT</span>\n<span class=\"grvsc-line\">     }</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<h3 id=\"step-4-implement-user-registration\" style=\"position:relative;\"><a href=\"#step-4-implement-user-registration\" aria-label=\"step 4 implement user registration permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 4: Implement User Registration</h3>\n<p>Before implementing the user registration functionality, you must first <a href=\"https://www.loginradius.com/developers/\">obtain the user registration endpoint URL from the LoginRadius API Docs</a>.</p>\n<p>After retrieving the endpoint URL, you need to send a POST request to the endpoint using the <code>Dio</code> package by passing in:</p>\n<ul>\n<li>the <code>apiKey</code> you obtained earlier as a query parameter;</li>\n<li>the <code>userData</code> as the request body; and,</li>\n<li>the <code>SOTT</code> key as a header, as shown below.</li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"dart\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">class ApiClient {</span>\n<span class=\"grvsc-line\">       //...</span>\n<span class=\"grvsc-line\">       Future&lt;Response&gt; registerUser(Map&lt;String, dynamic&gt;? userData) async {</span>\n<span class=\"grvsc-line\">        try {</span>\n<span class=\"grvsc-line\">          Response response = await _dio.post(</span>\n<span class=\"grvsc-line\">              &#39;https://api.loginradius.com/identity/v2/auth/register&#39;,  //ENDPONT URL</span>\n<span class=\"grvsc-line\">              data: userData, //REQUEST BODY</span>\n<span class=\"grvsc-line\">              queryParameters: {&#39;apikey&#39;: &#39;YOUR_API_KEY&#39;},  //QUERY PARAMETERS</span>\n<span class=\"grvsc-line\">              options: Options(headers: {&#39;X-LoginRadius-Sott&#39;: &#39;YOUR_SOTT_KEY&#39;, //HEADERS</span>\n<span class=\"grvsc-line\">          }));</span>\n<span class=\"grvsc-line\">          //returns the successful json object</span>\n<span class=\"grvsc-line\">          return response.data;</span>\n<span class=\"grvsc-line\">        } on DioError catch (e) {</span>\n<span class=\"grvsc-line\">          //returns the error object if there is</span>\n<span class=\"grvsc-line\">          return e.response!.data;</span>\n<span class=\"grvsc-line\">        }</span>\n<span class=\"grvsc-line\">      }</span>\n<span class=\"grvsc-line\">    }</span></code></pre>\n<h3 id=\"step-5-implement-user-login\" style=\"position:relative;\"><a href=\"#step-5-implement-user-login\" aria-label=\"step 5 implement user login permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 5: Implement User Login</h3>\n<p>The below code snippet shows how you’ll send a POST request to the LoginRadius login endpoint URL <code>https://api.loginradius.com/identity/v2/auth/login</code>, passing in your <code>apiKey</code> as a query parameter and the <code>email</code> and <code>password</code> of the user as the request body.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"dart\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">class ApiClient {</span>\n<span class=\"grvsc-line\">       //...</span>\n<span class=\"grvsc-line\">       Future&lt;Response&gt; login(String email, String password) async {</span>\n<span class=\"grvsc-line\">        try {</span>\n<span class=\"grvsc-line\">          Response response = await _dio.post(</span>\n<span class=\"grvsc-line\">            &#39;https://api.loginradius.com/identity/v2/auth/login&#39;,</span>\n<span class=\"grvsc-line\">            data: {</span>\n<span class=\"grvsc-line\">              &#39;email&#39;: email,</span>\n<span class=\"grvsc-line\">              &#39;password&#39;: password</span>\n<span class=\"grvsc-line\">            },</span>\n<span class=\"grvsc-line\">            queryParameters: {&#39;apikey&#39;: &#39;YOUR_API_KEY&#39;},</span>\n<span class=\"grvsc-line\">          );</span>\n<span class=\"grvsc-line\">          //returns the successful user data json object</span>\n<span class=\"grvsc-line\">          return response.data;</span>\n<span class=\"grvsc-line\">        } on DioError catch (e) {</span>\n<span class=\"grvsc-line\">          //returns the error object if any</span>\n<span class=\"grvsc-line\">          return e.response!.data;</span>\n<span class=\"grvsc-line\">        }</span>\n<span class=\"grvsc-line\">      }</span>\n<span class=\"grvsc-line\">    }</span></code></pre>\n<h3 id=\"step-6-get-user-profile-data\" style=\"position:relative;\"><a href=\"#step-6-get-user-profile-data\" aria-label=\"step 6 get user profile data permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 6: Get User Profile Data</h3>\n<p>To retrieve the user profile details, send a <code>GET</code> request to the Read Profile Endpoint URL <code>https://api.loginradius.com/identity/v2/auth/account</code>, passing in your <code>apiKey</code> as a query parameter and the user's access token as the header.</p>\n<blockquote>\n<p>The user’s access token is gotten from the successful response object of the User Login endpoint.</p>\n</blockquote>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"dart\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">class ApiClient {</span>\n<span class=\"grvsc-line\">       //...</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">       Future&lt;Response&gt; getUserProfileData(String accesstoken) async {</span>\n<span class=\"grvsc-line\">        try {</span>\n<span class=\"grvsc-line\">          Response response = await _dio.get(</span>\n<span class=\"grvsc-line\">            &#39;https://api.loginradius.com/identity/v2/auth/account&#39;,</span>\n<span class=\"grvsc-line\">            queryParameters: {&#39;apikey&#39;: &#39;YOUR_API_KEY&#39;},</span>\n<span class=\"grvsc-line\">            options: Options(</span>\n<span class=\"grvsc-line\">              headers: {</span>\n<span class=\"grvsc-line\">                &#39;Authorization&#39;: &#39;Bearer ${YOUR_ACCESS_TOKEN}&#39;,</span>\n<span class=\"grvsc-line\">              },</span>\n<span class=\"grvsc-line\">            ),</span>\n<span class=\"grvsc-line\">          );</span>\n<span class=\"grvsc-line\">          return response.data;</span>\n<span class=\"grvsc-line\">        } on DioError catch (e) {</span>\n<span class=\"grvsc-line\">          return e.response!.data;</span>\n<span class=\"grvsc-line\">        }</span>\n<span class=\"grvsc-line\">    }</span></code></pre>\n<h3 id=\"step-7-implement-user-logout\" style=\"position:relative;\"><a href=\"#step-7-implement-user-logout\" aria-label=\"step 7 implement user logout permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 7: Implement User Logout</h3>\n<p>Finally, to implement the user logout functionality, you would send a <code>GET</code> request to the Invalidate User Access Token endpoint URL <code>https://api.loginradius.com/identity/v2/auth/access_token/InValidate</code>. This API call invalidates the user's active access token, requiring them to re-authenticate if they want to access their data.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"dart\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">class ApiClient {</span>\n<span class=\"grvsc-line\">       //...</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">      Future&lt;Response&gt; logout(String accessToken) async {</span>\n<span class=\"grvsc-line\">        try {</span>\n<span class=\"grvsc-line\">          Response response = await _dio.get(</span>\n<span class=\"grvsc-line\">            &#39;https://api.loginradius.com/identity/v2/auth/access_token/InValidate&#39;,</span>\n<span class=\"grvsc-line\">            queryParameters: {&#39;apikey&#39;: ApiSecret.apiKey},</span>\n<span class=\"grvsc-line\">            options: Options(</span>\n<span class=\"grvsc-line\">              headers: {&#39;Authorization&#39;: &#39;Bearer $accessToken&#39;},</span>\n<span class=\"grvsc-line\">            ),</span>\n<span class=\"grvsc-line\">          );</span>\n<span class=\"grvsc-line\">          return response.data;</span>\n<span class=\"grvsc-line\">        } on DioError catch (e) {</span>\n<span class=\"grvsc-line\">          return e.response!.data;</span>\n<span class=\"grvsc-line\">        }</span>\n<span class=\"grvsc-line\">      }</span>\n<span class=\"grvsc-line\">    }</span></code></pre>\n<p>That concludes the <code>ApiClient</code> class. Next, you'll build the UI for your Flutter application, making use of the methods you just created in the <code>ApiClient</code> class.</p>\n<h3 id=\"building-the-ui\" style=\"position:relative;\"><a href=\"#building-the-ui\" aria-label=\"building the ui permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Building the UI</h3>\n<p>Your Flutter application will consist of four screens, which include:</p>\n<ul>\n<li>Registration Screen</li>\n<li>Login Screen</li>\n<li>Home Screen</li>\n</ul>\n<p>Let’s begin by building the Registration Screen.</p>\n<h3 id=\"registration-screen\" style=\"position:relative;\"><a href=\"#registration-screen\" aria-label=\"registration screen permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Registration Screen</h3>\n<p>The <code>RegistrationScreen</code> has two <code>TextFormField</code> widgets that serve as our <code>email</code> and <code>password</code> fields, as well as an <code>ElevatedButton</code> to handle event submission, as shown in the code snippet below from the <code>register.dart</code> file.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"dart\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"> //...</span>\n<span class=\"grvsc-line\">    @override</span>\n<span class=\"grvsc-line\">    Widget build(BuildContext context) {</span>\n<span class=\"grvsc-line\">      Scaffold(</span>\n<span class=\"grvsc-line\">          backgroundColor: Colors.blueGrey[200],</span>\n<span class=\"grvsc-line\">          body: Form(</span>\n<span class=\"grvsc-line\">            key: _formKey,</span>\n<span class=\"grvsc-line\">            child: SizedBox(</span>\n<span class=\"grvsc-line\">              width: size.width,</span>\n<span class=\"grvsc-line\">              height: size.height,</span>\n<span class=\"grvsc-line\">              child: Align(</span>\n<span class=\"grvsc-line\">                alignment: Alignment.center,</span>\n<span class=\"grvsc-line\">                child: Container(</span>\n<span class=\"grvsc-line\">                  width: size.width * 0.85,</span>\n<span class=\"grvsc-line\">                  padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 30),</span>\n<span class=\"grvsc-line\">                  decoration: BoxDecoration(</span>\n<span class=\"grvsc-line\">                    color: Colors.white,</span>\n<span class=\"grvsc-line\">                    borderRadius: BorderRadius.circular(20),</span>\n<span class=\"grvsc-line\">                  ),</span>\n<span class=\"grvsc-line\">                  child: SingleChildScrollView(</span>\n<span class=\"grvsc-line\">                    child: Column(</span>\n<span class=\"grvsc-line\">                      crossAxisAlignment: CrossAxisAlignment.start,</span>\n<span class=\"grvsc-line\">                      children: &lt;Widget&gt;[</span>\n<span class=\"grvsc-line\">                        const Center(</span>\n<span class=\"grvsc-line\">                          child: Text(</span>\n<span class=\"grvsc-line\">                            &quot;Register&quot;,</span>\n<span class=\"grvsc-line\">                            style: TextStyle(</span>\n<span class=\"grvsc-line\">                              fontSize: 30,</span>\n<span class=\"grvsc-line\">                              fontWeight: FontWeight.bold,</span>\n<span class=\"grvsc-line\">                            ),</span>\n<span class=\"grvsc-line\">                          ),</span>\n<span class=\"grvsc-line\">                        ),</span>\n<span class=\"grvsc-line\">                        SizedBox(height: size.height * 0.05),</span>\n<span class=\"grvsc-line\">                        TextFormField(</span>\n<span class=\"grvsc-line\">                          validator: (value) =&gt;</span>\n<span class=\"grvsc-line\">                              Validator.validateEmail(value ?? &quot;&quot;),</span>\n<span class=\"grvsc-line\">                          controller: emailController,</span>\n<span class=\"grvsc-line\">                          keyboardType: TextInputType.emailAddress,</span>\n<span class=\"grvsc-line\">                          decoration: InputDecoration(</span>\n<span class=\"grvsc-line\">                            hintText: &quot;Email&quot;,</span>\n<span class=\"grvsc-line\">                            isDense: true,</span>\n<span class=\"grvsc-line\">                            border: OutlineInputBorder(</span>\n<span class=\"grvsc-line\">                              borderRadius: BorderRadius.circular(10),</span>\n<span class=\"grvsc-line\">                            ),</span>\n<span class=\"grvsc-line\">                          ),</span>\n<span class=\"grvsc-line\">                        ),</span>\n<span class=\"grvsc-line\">                        SizedBox(height: size.height * 0.03),</span>\n<span class=\"grvsc-line\">                        TextFormField(</span>\n<span class=\"grvsc-line\">                          obscureText: _showPassword,</span>\n<span class=\"grvsc-line\">                          validator: (value) =&gt;</span>\n<span class=\"grvsc-line\">                              Validator.validatePassword(value ?? &quot;&quot;),</span>\n<span class=\"grvsc-line\">                          controller: passwordController,</span>\n<span class=\"grvsc-line\">                          keyboardType: TextInputType.visiblePassword,</span>\n<span class=\"grvsc-line\">                          decoration: InputDecoration(</span>\n<span class=\"grvsc-line\">                            hintText: &quot;Password&quot;,</span>\n<span class=\"grvsc-line\">                            isDense: true,</span>\n<span class=\"grvsc-line\">                            border: OutlineInputBorder(</span>\n<span class=\"grvsc-line\">                              borderRadius: BorderRadius.circular(10),</span>\n<span class=\"grvsc-line\">                            ),</span>\n<span class=\"grvsc-line\">                          ),</span>\n<span class=\"grvsc-line\">                        ),</span>\n<span class=\"grvsc-line\">                        SizedBox(height: size.height * 0.06),</span>\n<span class=\"grvsc-line\">                        Row(</span>\n<span class=\"grvsc-line\">                          mainAxisAlignment: MainAxisAlignment.center,</span>\n<span class=\"grvsc-line\">                          children: [</span>\n<span class=\"grvsc-line\">                            Expanded(</span>\n<span class=\"grvsc-line\">                              child: ElevatedButton(</span>\n<span class=\"grvsc-line\">                                onPressed: _handleRegister,</span>\n<span class=\"grvsc-line\">                                style: ElevatedButton.styleFrom(</span>\n<span class=\"grvsc-line\">                                    primary: Colors.indigo,</span>\n<span class=\"grvsc-line\">                                    shape: RoundedRectangleBorder(</span>\n<span class=\"grvsc-line\">                                        borderRadius: BorderRadius.circular(10)),</span>\n<span class=\"grvsc-line\">                                    padding: const EdgeInsets.symmetric(</span>\n<span class=\"grvsc-line\">                                        horizontal: 40, vertical: 15)),</span>\n<span class=\"grvsc-line\">                                child: const Text(</span>\n<span class=\"grvsc-line\">                                  &quot;Register&quot;,</span>\n<span class=\"grvsc-line\">                                  style: TextStyle(</span>\n<span class=\"grvsc-line\">                                    fontSize: 20,</span>\n<span class=\"grvsc-line\">                                    fontWeight: FontWeight.bold,</span>\n<span class=\"grvsc-line\">                                  ),</span>\n<span class=\"grvsc-line\">                                ),</span>\n<span class=\"grvsc-line\">                              ),</span>\n<span class=\"grvsc-line\">                            ),</span>\n<span class=\"grvsc-line\">                          ],</span>\n<span class=\"grvsc-line\">                        ),</span>\n<span class=\"grvsc-line\">                      ],</span>\n<span class=\"grvsc-line\">                    ),</span>\n<span class=\"grvsc-line\">                  ),</span>\n<span class=\"grvsc-line\">                ),</span>\n<span class=\"grvsc-line\">              ),</span>\n<span class=\"grvsc-line\">            ),</span>\n<span class=\"grvsc-line\">          ),</span>\n<span class=\"grvsc-line\">        );</span>\n<span class=\"grvsc-line\">    }</span>\n<span class=\"grvsc-line\">    //...</span></code></pre>\n<p>In the <code>onPressed</code> callback of the <code>ElevatedButton</code> widget, you'll handle the validation of your form data.</p>\n<p>If the form is validated, you pass your <code>userData</code> to the <code>registerUser</code> method from the <code>ApiClient</code> class for processing.</p>\n<p>If the response is an error, you show a snackbar with the error message. Otherwise, the user is redirected to the Login Screen.</p>\n<blockquote>\n<p>In the following example, you've provided only a few user attributes as <code>userData</code>. To view the complete list of user attributes, please look at the body parameters of the User Registration API here.</p>\n</blockquote>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"dart\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">Future&lt;void&gt; _handleRegister() async {</span>\n<span class=\"grvsc-line\">    if (_formKey.currentState!.validate()) {</span>\n<span class=\"grvsc-line\">    //show snackbar to indicate loading</span>\n<span class=\"grvsc-line\">     ScaffoldMessenger.of(context).showSnackBar(SnackBar(</span>\n<span class=\"grvsc-line\">        content: const Text(&#39;Processing Data&#39;),</span>\n<span class=\"grvsc-line\">        backgroundColor: Colors.green.shade300,</span>\n<span class=\"grvsc-line\">      ));</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">   //the user data to be sent</span>\n<span class=\"grvsc-line\">    Map&lt;String, dynamic&gt; userData = {</span>\n<span class=\"grvsc-line\">      &quot;Email&quot;: [</span>\n<span class=\"grvsc-line\">        {</span>\n<span class=\"grvsc-line\">          &quot;Type&quot;: &quot;Primary&quot;,</span>\n<span class=\"grvsc-line\">          &quot;Value&quot;: emailController.text,</span>\n<span class=\"grvsc-line\">        }</span>\n<span class=\"grvsc-line\">      ],</span>\n<span class=\"grvsc-line\">      &quot;Password&quot;: passwordController.text,</span>\n<span class=\"grvsc-line\">      &quot;About&quot;: &#39;I am a new user :smile:&#39;,</span>\n<span class=\"grvsc-line\">      &quot;FirstName&quot;: &quot;Test&quot;,</span>\n<span class=\"grvsc-line\">      &quot;LastName&quot;: &quot;Account&quot;,</span>\n<span class=\"grvsc-line\">      &quot;BirthDate&quot;: &quot;10-12-1985&quot;,</span>\n<span class=\"grvsc-line\">      &quot;Gender&quot;: &quot;M&quot;,</span>\n<span class=\"grvsc-line\">    };</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">    //get response from ApiClient</span>\n<span class=\"grvsc-line\">    dynamic res = await _apiClient.registerUser(userData);</span>\n<span class=\"grvsc-line\">    ScaffoldMessenger.of(context).hideCurrentSnackBar();</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">    //checks if there is no error in the response body.</span>\n<span class=\"grvsc-line\">    //if error is not present, navigate the users to Login Screen.</span>\n<span class=\"grvsc-line\">    if (res[&#39;ErrorCode&#39;] == null) {</span>\n<span class=\"grvsc-line\">      Navigator.push(context,</span>\n<span class=\"grvsc-line\">          MaterialPageRoute(builder: (context) =&gt; const LoginScreen()));</span>\n<span class=\"grvsc-line\">    } else {</span>\n<span class=\"grvsc-line\">     //if error is present, display a snackbar showing the error messsage</span>\n<span class=\"grvsc-line\">      ScaffoldMessenger.of(context).showSnackBar(SnackBar(</span>\n<span class=\"grvsc-line\">        content: Text(&#39;Error: ${res[&#39;Message&#39;]}&#39;),</span>\n<span class=\"grvsc-line\">        backgroundColor: Colors.red.shade300,</span>\n<span class=\"grvsc-line\">      ));</span>\n<span class=\"grvsc-line\">    }</span>\n<span class=\"grvsc-line\">  }</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<h3 id=\"login-screen\" style=\"position:relative;\"><a href=\"#login-screen\" aria-label=\"login screen permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Login Screen</h3>\n<p>The <code>LoginScreen</code> UI code is similar to the <code>RegistrationScreen</code> in that it also has two <code>TextFormField</code> widgets that serve as our <code>email</code> and <code>password</code> fields, as well as an <code>ElevatedButton</code> to handle event submission. So, for the sake of brevity, I’ll be leaving out the <code>LoginScreen</code> UI code and focusing mainly on the code to be written in the <code>ElevatedButton</code> onPressed callback in the <code>login_screen.dart</code> file.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"dart\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">//...</span>\n<span class=\"grvsc-line\">    //...</span>\n<span class=\"grvsc-line\">       Future&lt;void&gt; loginUsers() async {</span>\n<span class=\"grvsc-line\">        if (_formKey.currentState!.validate()) {</span>\n<span class=\"grvsc-line\">          //show snackbar to indicate loading</span>\n<span class=\"grvsc-line\">          ScaffoldMessenger.of(context).showSnackBar(SnackBar(</span>\n<span class=\"grvsc-line\">            content: const Text(&#39;Processing Data&#39;),</span>\n<span class=\"grvsc-line\">            backgroundColor: Colors.green.shade300,</span>\n<span class=\"grvsc-line\">          ));</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">          //get response from ApiClient</span>\n<span class=\"grvsc-line\">          dynamic res = await _apiClient.login(</span>\n<span class=\"grvsc-line\">            emailController.text,</span>\n<span class=\"grvsc-line\">            passwordController.text,</span>\n<span class=\"grvsc-line\">          );</span>\n<span class=\"grvsc-line\">          ScaffoldMessenger.of(context).hideCurrentSnackBar();</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">          //if there is no error, get the user&#39;s accesstoken and pass it to HomeScreen</span>\n<span class=\"grvsc-line\">          if (res[&#39;ErrorCode&#39;] == null) {</span>\n<span class=\"grvsc-line\">            String accessToken = res[&#39;access_token&#39;];</span>\n<span class=\"grvsc-line\">            Navigator.push(</span>\n<span class=\"grvsc-line\">                context,</span>\n<span class=\"grvsc-line\">                MaterialPageRoute(</span>\n<span class=\"grvsc-line\">                    builder: (context) =&gt; HomeScreen(accesstoken: accessToken)));</span>\n<span class=\"grvsc-line\">          } else {</span>\n<span class=\"grvsc-line\">          //if an error occurs, show snackbar with error message</span>\n<span class=\"grvsc-line\">          ScaffoldMessenger.of(context).showSnackBar(SnackBar(</span>\n<span class=\"grvsc-line\">            content: Text(&#39;Error: ${res[&#39;Message&#39;]}&#39;),</span>\n<span class=\"grvsc-line\">            backgroundColor: Colors.red.shade300,</span>\n<span class=\"grvsc-line\">          ));</span>\n<span class=\"grvsc-line\">          }</span>\n<span class=\"grvsc-line\">        }</span>\n<span class=\"grvsc-line\">      }</span>\n<span class=\"grvsc-line\">    //...</span></code></pre>\n<p>The code snippet above is a method that first validates the form before passing the <code>email</code> and <code>password</code> values to the <code>login</code> method from the <code>ApiClient</code> class for handling.</p>\n<p>If the response is successful, you obtain the user’s <code>access_token</code> from the response data and pass it over to the <code>HomeScreen</code>. Otherwise, you display a snackbar with the error message that occurred.</p>\n<p>Then, you pass the <code>loginUsers</code> method you created above to the <code>onPressed</code> property of the <code>ElevatedButton</code> widget in the <code>LoginScreen</code>, as shown below.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"dart\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">    ElevatedButton(</span>\n<span class=\"grvsc-line\">        onPressed: loginUsers, //&lt;--</span>\n<span class=\"grvsc-line\">        style: ElevatedButton.styleFrom(</span>\n<span class=\"grvsc-line\">        primary: Colors.indigo,</span>\n<span class=\"grvsc-line\">        shape: RoundedRectangleBorder(</span>\n<span class=\"grvsc-line\">               borderRadius: BorderRadius.circular(10)),</span>\n<span class=\"grvsc-line\">               padding: const EdgeInsets.symmetric(</span>\n<span class=\"grvsc-line\">                        horizontal: 40, vertical: 15)),</span>\n<span class=\"grvsc-line\">        child: const Text(&quot;Login&quot;,</span>\n<span class=\"grvsc-line\">            style: TextStyle(</span>\n<span class=\"grvsc-line\">                fontSize: 20,</span>\n<span class=\"grvsc-line\">                fontWeight: FontWeight.bold,</span>\n<span class=\"grvsc-line\">            ),</span>\n<span class=\"grvsc-line\">           ),</span>\n<span class=\"grvsc-line\">         ),</span>\n<span class=\"grvsc-line\">       ),</span></code></pre>\n<p>Next, you need to provide a screen that reveals the user's profile data when they successfully log in, and the <code>HomeScreen</code> is there to do so.</p>\n<h3 id=\"home-screen\" style=\"position:relative;\"><a href=\"#home-screen\" aria-label=\"home screen permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Home Screen</h3>\n<p>The <code>HomeScreen</code> displays the user’s profile details using a <code>FutureBuilder</code> widget that accepts a future <code>getUserData</code>.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"dart\" data-index=\"12\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">      Future&lt;Map&lt;String, dynamic&gt;&gt; getUserData() async {</span>\n<span class=\"grvsc-line\">        dynamic userRes;</span>\n<span class=\"grvsc-line\">        userRes = await _apiClient.getUserProfileData(widget.accesstoken);</span>\n<span class=\"grvsc-line\">        return userRes;</span>\n<span class=\"grvsc-line\">      }</span></code></pre>\n<p>The <code>getUserData</code> method above is used to retrieve details of a user by passing in the <code>access_token</code> obtained earlier from the <code>LoginScreen</code> to the <code>ApiClient</code> <code>getUserProfileData</code> method.</p>\n<p>To display the result of your <code>getUserData</code> method on our screen, use a <code>FutureBuilder</code> widget. The code snippet below shows how to use the <code>FutureBuilder</code> to get the results of the <code>getUserData</code> future in the <code>home.dart</code> file.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"dart\" data-index=\"13\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">    class HomeScreen extends StatefulWidget {</span>\n<span class=\"grvsc-line\">      final String accesstoken;</span>\n<span class=\"grvsc-line\">      const HomeScreen({Key? key, required this.accesstoken}) : super(key: key);</span>\n<span class=\"grvsc-line\">      @override</span>\n<span class=\"grvsc-line\">      State&lt;HomeScreen&gt; createState() =&gt; _HomeScreenState();</span>\n<span class=\"grvsc-line\">    }</span>\n<span class=\"grvsc-line\">    class _HomeScreenState extends State&lt;HomeScreen&gt; {</span>\n<span class=\"grvsc-line\">      //instance of ApiClient class</span>\n<span class=\"grvsc-line\">      final ApiClient _apiClient = ApiClient();</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">      //get user data from ApiClient</span>\n<span class=\"grvsc-line\">      Future&lt;Map&lt;String, dynamic&gt;&gt; getUserData() async {</span>\n<span class=\"grvsc-line\">        dynamic userRes;</span>\n<span class=\"grvsc-line\">        userRes = await _apiClient.getUserProfileData(widget.accesstoken);</span>\n<span class=\"grvsc-line\">        return userRes;</span>\n<span class=\"grvsc-line\">      }</span>\n<span class=\"grvsc-line\">      @override</span>\n<span class=\"grvsc-line\">      Widget build(BuildContext context) {</span>\n<span class=\"grvsc-line\">        var size = MediaQuery.of(context).size;</span>\n<span class=\"grvsc-line\">        return Scaffold(</span>\n<span class=\"grvsc-line\">          backgroundColor: Colors.white,</span>\n<span class=\"grvsc-line\">          body: SizedBox(</span>\n<span class=\"grvsc-line\">              width: size.width,</span>\n<span class=\"grvsc-line\">              height: size.height,</span>\n<span class=\"grvsc-line\">              child: FutureBuilder&lt;Map&lt;String, dynamic&gt;&gt;(</span>\n<span class=\"grvsc-line\">                future: getUserData(), //&lt;---</span>\n<span class=\"grvsc-line\">                builder: (context, snapshot) {</span>\n<span class=\"grvsc-line\">                  if (snapshot.hasData) {</span>\n<span class=\"grvsc-line\">                    if (snapshot.connectionState == ConnectionState.waiting) {</span>\n<span class=\"grvsc-line\">                      return Container(</span>\n<span class=\"grvsc-line\">                        height: size.height,</span>\n<span class=\"grvsc-line\">                        width: size.width,</span>\n<span class=\"grvsc-line\">                        color: Colors.blueGrey,</span>\n<span class=\"grvsc-line\">                        child: const Center(</span>\n<span class=\"grvsc-line\">                          child: CircularProgressIndicator(),</span>\n<span class=\"grvsc-line\">                        ),</span>\n<span class=\"grvsc-line\">                      );</span>\n<span class=\"grvsc-line\">                    }</span>\n<span class=\"grvsc-line\">                    //get results from snapshot</span>\n<span class=\"grvsc-line\">                    String fullName = snapshot.data![&#39;FullName&#39;];</span>\n<span class=\"grvsc-line\">                    String firstName = snapshot.data![&#39;FirstName&#39;];</span>\n<span class=\"grvsc-line\">                    String lastName = snapshot.data![&#39;LastName&#39;];</span>\n<span class=\"grvsc-line\">                    String birthDate = snapshot.data![&#39;BirthDate&#39;];</span>\n<span class=\"grvsc-line\">                    String email = snapshot.data![&#39;Email&#39;][0][&#39;Value&#39;];</span>\n<span class=\"grvsc-line\">                    String gender = snapshot.data![&#39;Gender&#39;];</span>\n<span class=\"grvsc-line\">                    return Container(</span>\n<span class=\"grvsc-line\">                      width: size.width,</span>\n<span class=\"grvsc-line\">                      height: size.height,</span>\n<span class=\"grvsc-line\">                      color: Colors.blueGrey.shade400,</span>\n<span class=\"grvsc-line\">                      child: SingleChildScrollView(</span>\n<span class=\"grvsc-line\">                        physics: const BouncingScrollPhysics(),</span>\n<span class=\"grvsc-line\">                     //...</span>\n<span class=\"grvsc-line\">                //...</span></code></pre>\n<p>Finally, let's add the logout feature.</p>\n<p>Add an <code>ElevatedButton</code> widget to the <code>HomeScreen</code>.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"dart\" data-index=\"14\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">     TextButton(</span>\n<span class=\"grvsc-line\">        onPressed: (){},</span>\n<span class=\"grvsc-line\">        style: TextButton.styleFrom(</span>\n<span class=\"grvsc-line\">        backgroundColor: Colors.redAccent.shade700,</span>\n<span class=\"grvsc-line\">        shape: RoundedRectangleBorder(</span>\n<span class=\"grvsc-line\">               borderRadius: BorderRadius.circular(5)),</span>\n<span class=\"grvsc-line\">               padding: const EdgeInsets.symmetric(</span>\n<span class=\"grvsc-line\">                    vertical: 15, horizontal: 25)),</span>\n<span class=\"grvsc-line\">        child: const Text(&#39;Logout&#39;,</span>\n<span class=\"grvsc-line\">          style: TextStyle(color: Colors.white),           ),</span>\n<span class=\"grvsc-line\">        ),</span>\n<span class=\"grvsc-line\">     ),</span></code></pre>\n<p>On pressing the button, you'll call the <code>logout</code> method on the <code>ApiClient</code> class and pass in the <code>access_token</code> value, and then you route the user to the <code>LoginScreen</code>.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"dart\" data-index=\"15\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">     TextButton(</span>\n<span class=\"grvsc-line\">        onPressed: () async {</span>\n<span class=\"grvsc-line\">          await _apiClient.logout(widget.accesstoken);</span>\n<span class=\"grvsc-line\">          Navigator.pushReplacement(</span>\n<span class=\"grvsc-line\">            context, MaterialPageRoute(builder: (context) =&gt; const LoginScreen()));</span>\n<span class=\"grvsc-line\">        },</span>\n<span class=\"grvsc-line\">        style: TextButton.styleFrom(</span>\n<span class=\"grvsc-line\">        backgroundColor: Colors.redAccent.shade700,</span>\n<span class=\"grvsc-line\">        shape: RoundedRectangleBorder(</span>\n<span class=\"grvsc-line\">               borderRadius: BorderRadius.circular(5)),</span>\n<span class=\"grvsc-line\">               padding: const EdgeInsets.symmetric(</span>\n<span class=\"grvsc-line\">                    vertical: 15, horizontal: 25)),</span>\n<span class=\"grvsc-line\">        child: const Text(&#39;Logout&#39;,</span>\n<span class=\"grvsc-line\">             style: TextStyle(color: Colors.white),</span>\n<span class=\"grvsc-line\">          ),</span>\n<span class=\"grvsc-line\">     ),</span></code></pre>\n<p><img src=\"/968d860d94a6f5f996e709e22dcec84a/demo-project.gif\" alt=\"Preview of demo project\"></p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>LoginRadius provides high-level, secure, and well-documented APIs to ease the implementation of authentication and user identity management. This tutorial has discussed LoginRadius's benefits and how to use the LoginRadius APIs to handle user authentication and registration in a Flutter application.</p>\n<p>The complete <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/Flutter/Flutter_Auth_Guide\">source code of the demo application is available on GitHub</a>.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n</style>","frontmatter":{"date":"February 17, 2022","updated_date":null,"description":"Developing Flutter apps? Learn how to implement user authentication and registration in your Flutter applications quickly with LoginRadius APIs.","title":"Flutter Authentication: Implementing User Signup and Login","tags":["Authentication","Flutter","API"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/97c4aaf6f0e898b457c0574ba1f8c979/58556/user-authentication-for-flutter-apps.webp","srcSet":"/static/97c4aaf6f0e898b457c0574ba1f8c979/61e93/user-authentication-for-flutter-apps.webp 200w,\n/static/97c4aaf6f0e898b457c0574ba1f8c979/1f5c5/user-authentication-for-flutter-apps.webp 400w,\n/static/97c4aaf6f0e898b457c0574ba1f8c979/58556/user-authentication-for-flutter-apps.webp 800w,\n/static/97c4aaf6f0e898b457c0574ba1f8c979/99238/user-authentication-for-flutter-apps.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Yusuf Ahmed","github":null,"avatar":null}}}},{"node":{"excerpt":"Authentication and authorization are critical in every software application to secure user data and allow access to trusted users. In some…","fields":{"slug":"/engineering/guest-post/loopback-rest-api-authentication/"},"html":"<p>Authentication and authorization are critical in every software application to secure user data and allow access to trusted users. In some cases, implementing authentication and authorization is not an easy process.</p>\n<p>However, LoopBack 4 offers an authentication package <strong>@loopback/authentication</strong> that helps secure your application's API endpoints. It provides custom authentication strategies and a <strong>@authenticate</strong> decorator that requires minimal boilerplate code.</p>\n<h2 id=\"what-is-loopback\" style=\"position:relative;\"><a href=\"#what-is-loopback\" aria-label=\"what is loopback permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is LoopBack?</h2>\n<p>According to the <a href=\"https://loopback.io/doc/en/lb4/index.html\">LoopBack 4 documentation</a>:</p>\n<blockquote>\n<p>LoopBack is a flexible, open source Node.js and TypeScript framework built on Express. It helps you quickly develop APIs and microservices built on backend systems such as databases and SOAP or REST services.</p>\n</blockquote>\n<p>Loopback provides several features that allow you to build your application with less boilerplate code.</p>\n<h2 id=\"what-is-json-web-token-jwt\" style=\"position:relative;\"><a href=\"#what-is-json-web-token-jwt\" aria-label=\"what is json web token jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is JSON Web Token (JWT)?</h2>\n<p>JSON Web Token (JWT) is an open standard <a href=\"https://datatracker.ietf.org/doc/html/rfc7519.html\">defined by Internet Engineering Task Force (IETF) in RFC 7519</a>.</p>\n<p>It is a standard used for securely transferring claims between two parties over the internet. It uses JSON Web Signature (JWS) for the secure transfer of claims and eliminates the possibility of tampering. Accordingly, JWTs can be signed with either a secret (HMAC technique) or a public/private key pair (RSA or ECDSA).</p>\n<p>In simple words, it is used for authentication and secure information sharing. A JWT token is made up of three components that are separated by three dots:</p>\n<ul>\n<li><strong>Header:</strong> The header is made up of two parts — the kind of token, which is JWT; the signature technique used, either HMAC SHA256 or RSA.</li>\n<li><strong>Payload:</strong> The payload is the token, which includes the claims. Claims are assertions about an entity that provides extra information.</li>\n<li><strong>Signature:</strong> The encoded header, encoded payload, a secret, and the algorithm provided in the header comprise the signature.</li>\n</ul>\n<blockquote>\n<p>You can learn more about <a href=\"https://www.loginradius.com/blog/engineering/guest-post/jwt-authentication-best-practices-and-when-to-use/\">JWT and its best practices here</a>.</p>\n</blockquote>\n<h2 id=\"prerequisites\" style=\"position:relative;\"><a href=\"#prerequisites\" aria-label=\"prerequisites permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Prerequisites</h2>\n<p>This tutorial is a hands-on demonstration. To follow along, be sure you have the following in place:</p>\n<ul>\n<li>A Linux machine — This tutorial will use Ubuntu 20.04.3 LTS (Focal Fossa). The tutorial also works well on other Linux distributions and operating systems.</li>\n<li><a href=\"https://nodejs.org/\"><strong>NodeJS</strong></a> — JavaScript runtime built on Chrome's V8 JavaScript engine.</li>\n<li><a href=\"https://www.mongodb.com/\"><strong>MongoDB</strong></a> — Document-oriented database program.</li>\n</ul>\n<h2 id=\"install-loopback-cli\" style=\"position:relative;\"><a href=\"#install-loopback-cli\" aria-label=\"install loopback cli permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Install LoopBack CLI</h2>\n<p>To start building your LoopBack REST API, first install LoopBack CLI, which provides the quickest method to create a LoopBack 4 project that follows best practices.</p>\n<p>Use the command below to install the Loopback CLI globally:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">npm i -g @loopback/cli</span></span></code></pre>\n<p>You can grab a cup of coffee while you wait for the installation to complete. Then open your command line, create an <code>AuthWithLooback</code> folder, and change the directory to the <code>AuthWithLooback</code> folder with commands below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">mkdir AuthWithLooback</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">cd</span><span class=\"mtk1\"> AuthWithLooback</span></span></code></pre>\n<h2 id=\"scaffold-your-loopback-project\" style=\"position:relative;\"><a href=\"#scaffold-your-loopback-project\" aria-label=\"scaffold your loopback project permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Scaffold Your LoopBack Project</h2>\n<p>So, you've installed Loopback CLI and created a project directory. Let's run the following command to create a LoopBack project:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">lb4 app</span></span></code></pre>\n<p>Select the options as in the following screenshot to complete the prompts.</p>\n<p><img src=\"/982c31e4e0a8b99735b9e920e72e898f/l5wg0nTQ.webp\" alt=\"Creating a loopback project\"></p>\n<p>After completing the prompts, LoopBack will configure the TypeScript compiler and install all the required dependencies. Change directory to the <code>auth-with-loopback</code> folder.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">cd</span><span class=\"mtk1\"> auth-with-loopback</span></span></code></pre>\n<h2 id=\"create-a-model\" style=\"position:relative;\"><a href=\"#create-a-model\" aria-label=\"create a model permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create a Model</h2>\n<p>You've successfully created your Loopback application. Now, let’s create a Model to store the news details with the command below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">lb4 model</span></span></code></pre>\n<p>Select the options as in the following screenshot to complete the prompts.</p>\n<p><img src=\"/3f73bef6f5422b16cc466d5f279701a9/lSCGXHs.webp\" alt=\"Creating a News Model\"></p>\n<p>After the <code>date_created</code> property definition, press the enter key to exit the prompt.</p>\n<p>Loopback will create a <code>NewsModel</code> file in the <code>src/models</code> — the folder where <code>NewsModel</code> will be defined.</p>\n<p>Next, you need to create a data source to connect to your preferred database. For demonstration, this tutorial connects to a MongoDB database.</p>\n<p>Run the following command in your terminal to create a data source:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">  lb4 datasource</span></span></code></pre>\n<p>Select the options as in the following screenshot to complete the prompts.</p>\n<p><img src=\"/aa8582e5de5c7011c46a43242342a5d2/pHvPgEQA.webp\" alt=\"Creating News datasource\"></p>\n<p>After completing the prompts, LoopBack will create the <code>News</code> file in the <code>src/datasource</code> folder.</p>\n<p>Then, create a <a href=\"https://loopback.io/doc/en/lb4/Repository.html\">Repository</a> for CRUD operations of your NewModel with the command below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">lb4 repository</span></span></code></pre>\n<p>After completing the prompts, LoopBack will create the <code>NewsModelRepository</code> file in the <code>src/repository</code> folder.</p>\n<p>Select <code>NewsDatasource</code> as the data source, <code>NewsModel</code> as the model for generating the repository, and <code>DefaultCrudRepository</code> as the base repository class.</p>\n<p>Your selection for the prompts shall look like the screenshot below.</p>\n<p><img src=\"/7789349e93d10cfc0800e4f822e581ca/WWH5tYJQ.webp\" alt=\"Creating News Repository\"></p>\n<p>After completing the prompts, LoopBack will create the <code>NewsModelRepository</code> file in the <code>src/repository</code> folder.</p>\n<p>Lastly, create a controller for the <code>NewsModel</code> you created with the command below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">  lb4 controller</span></span></code></pre>\n<p>Your selection for the prompts should look like the screenshot below.</p>\n<p><img src=\"/a22f45625db4bd560279a422e127665f/iHD6lPCg.webp\" alt=\"Creating News Controller\"></p>\n<p>After completing the prompts, LoopBack will create the <code>NewsController</code> file in the <code>src/controller</code> folder. So far, your project structure, omitting the <code>node_modules</code> folder, should look as follows.</p>\n<p>📦auth-with-loopback<br>\n┣ 📂public<br>\n┃ ┗ 📜index.html<br>\n┣ 📂src<br>\n┃ ┣ 📂<strong>tests</strong><br>\n┃ ┃ ┣ 📂acceptance<br>\n┃ ┃ ┃ ┣ 📜home-page.acceptance.ts<br>\n┃ ┃ ┃ ┣ 📜ping.controller.acceptance.ts<br>\n┃ ┃ ┃ ┗ 📜test-helper.ts<br>\n┃ ┃ ┗ 📜README.md<br>\n┃ ┣ 📂controllers<br>\n┃ ┃ ┣ 📜README.md<br>\n┃ ┃ ┣ 📜index.ts<br>\n┃ ┃ ┣ 📜news-controller.controller.ts<br>\n┃ ┃ ┗ 📜ping.controller.ts<br>\n┃ ┣ 📂datasources<br>\n┃ ┃ ┣ 📜README.md<br>\n┃ ┃ ┣ 📜index.ts<br>\n┃ ┃ ┗ 📜news.datasource.ts<br>\n┃ ┣ 📂models<br>\n┃ ┃ ┣ 📜README.md<br>\n┃ ┃ ┣ 📜index.ts<br>\n┃ ┃ ┗ 📜news-model.model.ts<br>\n┃ ┣ 📂repositories<br>\n┃ ┃ ┣ 📜README.md<br>\n┃ ┃ ┣ 📜index.ts<br>\n┃ ┃ ┗ 📜news-model.repository.ts<br>\n┃ ┣ 📜application.ts<br>\n┃ ┣ 📜index.ts<br>\n┃ ┣ 📜migrate.ts<br>\n┃ ┣ 📜openapi-spec.ts<br>\n┃ ┗ 📜sequence.ts<br>\n┣ 📜.dockerignore<br>\n┣ 📜.eslintignore<br>\n┣ 📜.eslintrc.js<br>\n┣ 📜.gitignore<br>\n┣ 📜.mocharc.json<br>\n┣ 📜.prettierignore<br>\n┣ 📜.prettierrc<br>\n┣ 📜.yo-rc.json<br>\n┣ 📜DEVELOPING.md<br>\n┣ 📜Dockerfile<br>\n┣ 📜README.md<br>\n┣ 📜package-lock.json<br>\n┣ 📜package.json<br>\n┗ 📜tsconfig.json</p>\n<h2 id=\"add-custom-data\" style=\"position:relative;\"><a href=\"#add-custom-data\" aria-label=\"add custom data permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Add Custom Data</h2>\n<p>Now that you have the Model setup, run the server, and add some custom data to the News collection in MongoDB.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">#start the server</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    npm run start</span></span></code></pre>\n<p>The above command will start the TypeScript compiler, which will build the project and check for possible errors. If everything goes well with the code, you should see the output on the terminal, as follows:</p>\n<p><img src=\"/cf1c4681ababa5101284b580193e8bf3/lSCGXHnw.webp\" alt=\"Starting LoopBack Server\"></p>\n<p>Next, open your favorite browser and navigate to <code>http://localhost:3000</code>. You should see an output as follows:</p>\n<p><img src=\"/321018f4c7be6074ce493ab2f711a5c2/hL9y8IIg.webp\" alt=\"LoopBack API Dashboard\"></p>\n<p>Now, click on the explorer link, where you can make requests to your LoopBack application. On the explorer page, locate the post endpoint and add some custom data to the news collection by clicking the <code>try it out</code> button with the data below on the request body.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"json\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">&quot;title&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Upgrade to Loopback V4&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">&quot;body&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;The developers of Loopback urges the V3 users to upgrade to V4 as soon as possible&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">&quot;date_created&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;2021-12-14T00:57:43.197Z&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Then, click the <code>execute</code> button to run the query.</p>\n<p><img src=\"/905e332f7af326f984c298c9a6239c41/jiC_1P0A.webp\" alt=\"Executing Queries\"></p>\n<p>You can add as many records as you like to experiment with the endpoints. The important thing to note here is that the endpoints are not protected. Anyone may create, read, update, and delete records.</p>\n<p>In a moment, this tutorial explains how to secure the endpoints so that only logged-in users can access them.</p>\n<p>To begin, install LoopBack <code>authentication</code> and <code>authentication-jwt</code>, as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">  npm i --save @loopback/authentication @loopback/authentication-jwt</span></span></code></pre>\n<h2 id=\"setup-authentication-components\" style=\"position:relative;\"><a href=\"#setup-authentication-components\" aria-label=\"setup authentication components permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Setup Authentication Components</h2>\n<p>To protect the application, you'll implement user authentication and authorization, which implies that only logged-in users will be able to access your APIs. You'll create two endpoints in the User controller:</p>\n<ul>\n<li><code>/Signup</code> endpoint: To handle user’s sign up.</li>\n<li><code>/Login</code> endpoint: To handle user’s login.</li>\n</ul>\n<h3 id=\"create-your-signup-endpoint\" style=\"position:relative;\"><a href=\"#create-your-signup-endpoint\" aria-label=\"create your signup endpoint permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create Your Signup Endpoint</h3>\n<p>You’ll start with the signup controller to enable users to create an account. Create an empty controller with the command below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    lb4 controller</span></span></code></pre>\n<p>Your selection for the prompts should be as follows:</p>\n<p><img src=\"/c0653ec5c8a0f68a48e55ff2159137d4/6LCgT-Gw.webp\" alt=\"Creating User Controller\"></p>\n<p>Then, open the <code>src/controllers/user.controller.ts</code> file, and import the required modules with the following code snippet:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"12\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">authenticate</span><span class=\"mtk1\">, </span><span class=\"mtk12\">TokenService</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@loopback/authentication&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Credentials</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">MyUserService</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">TokenServiceBindings</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">User</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">UserRepository</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">UserServiceBindings</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@loopback/authentication-jwt&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">inject</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@loopback/core&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">model</span><span class=\"mtk1\">, </span><span class=\"mtk12\">property</span><span class=\"mtk1\">, </span><span class=\"mtk12\">repository</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@loopback/repository&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">get</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">getModelSchemaRef</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">post</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">requestBody</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">SchemaObject</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@loopback/rest&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">SecurityBindings</span><span class=\"mtk1\">, </span><span class=\"mtk12\">securityId</span><span class=\"mtk1\">, </span><span class=\"mtk12\">UserProfile</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@loopback/security&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">genSalt</span><span class=\"mtk1\">, </span><span class=\"mtk12\">hash</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;bcryptjs&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">_</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;lodash&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ........</span></span></code></pre>\n<p>Next, set up your user credential objects, and verify the user credentials using the <code>UserService</code>, injecting <code>MyUserService</code> into the <code>authentication-jwt</code> extension.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"13\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    @</span><span class=\"mtk11\">model</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">CreateUser</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">User</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">property</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;string&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">required:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">password</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">UserSchema</span><span class=\"mtk1\">: </span><span class=\"mtk10\">SchemaObject</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;object&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">required:</span><span class=\"mtk1\"> [</span><span class=\"mtk8\">&#39;email&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;password&#39;</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">properties:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">email:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;string&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">format:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;email&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;string&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">minLength:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">6</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">RequestBody</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">description:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;The input of login function&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">required:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">content:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">schema:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">UserSchema</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">UserController</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        @</span><span class=\"mtk11\">inject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">TokenServiceBindings</span><span class=\"mtk1\">.</span><span class=\"mtk12\">TOKEN_SERVICE</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jwtService</span><span class=\"mtk1\">: </span><span class=\"mtk10\">TokenService</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        @</span><span class=\"mtk11\">inject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">UserServiceBindings</span><span class=\"mtk1\">.</span><span class=\"mtk12\">USER_SERVICE</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk12\">userService</span><span class=\"mtk1\">: </span><span class=\"mtk10\">MyUserService</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        @</span><span class=\"mtk11\">inject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">SecurityBindings</span><span class=\"mtk1\">.</span><span class=\"mtk12\">USER</span><span class=\"mtk1\">, { </span><span class=\"mtk12\">optional:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UserProfile</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        @</span><span class=\"mtk11\">repository</span><span class=\"mtk1\">(</span><span class=\"mtk12\">UserRepository</span><span class=\"mtk1\">) </span><span class=\"mtk4\">protected</span><span class=\"mtk1\"> </span><span class=\"mtk12\">userRepository</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UserRepository</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      ) { }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ..........</span></span></code></pre>\n<p>Finally, you'll build your signup endpoint, which will listen to POST requests. Here, you shall save the hashed version of the user's password in the database to keep it safe.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"14\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">     @</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/signup&#39;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">responses:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&#39;200&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">description:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;User&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">content:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">schema:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&#39;x-ts-type&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">signUp</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">requestBody</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">content:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">schema:</span><span class=\"mtk1\"> </span><span class=\"mtk11\">getModelSchemaRef</span><span class=\"mtk1\">(</span><span class=\"mtk12\">CreateUser</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">title:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;NewUser&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">newUserRequest</span><span class=\"mtk1\">: </span><span class=\"mtk12\">CreateUser</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ): </span><span class=\"mtk10\">Promise</span><span class=\"mtk1\">&lt;</span><span class=\"mtk12\">User</span><span class=\"mtk1\">&gt; {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">hash</span><span class=\"mtk1\">(</span><span class=\"mtk12\">newUserRequest</span><span class=\"mtk1\">.</span><span class=\"mtk12\">password</span><span class=\"mtk1\">, </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">genSalt</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const </span><span class=\"mtk12\">savedUser</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">userRepository</span><span class=\"mtk1\">.</span><span class=\"mtk11\">create</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">_</span><span class=\"mtk1\">.</span><span class=\"mtk11\">omit</span><span class=\"mtk1\">(</span><span class=\"mtk12\">newUserRequest</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;password&#39;</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      );</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      await this.userRepository.userCredentials(savedUser.id).create({ </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> });</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">savedUser</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .........</span></span></code></pre>\n<h3 id=\"create-your-login-controller\" style=\"position:relative;\"><a href=\"#create-your-login-controller\" aria-label=\"create your login controller permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create Your Login Controller</h3>\n<p>Now that you've set up the signup endpoint, create the login endpoint so that registered users may log in to the API.</p>\n<p>Using the code snippet below, set up the login route in the <code>src/controllers/user.controller.ts</code> file. In the event of a successful log-in, a token is sent to the user.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"15\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/signin&#39;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">responses:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&#39;200&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">description:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;Token&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">content:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">schema:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;object&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">properties:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                  </span><span class=\"mtk12\">token:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;string&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">signIn</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">requestBody</span><span class=\"mtk1\">(</span><span class=\"mtk12\">RequestBody</span><span class=\"mtk1\">) </span><span class=\"mtk12\">credentials</span><span class=\"mtk1\">: </span><span class=\"mtk12\">Credentials</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ): </span><span class=\"mtk10\">Promise</span><span class=\"mtk1\">&lt;{ token: </span><span class=\"mtk12\">string</span><span class=\"mtk1\"> }&gt; {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">userService</span><span class=\"mtk1\">.</span><span class=\"mtk11\">verifyCredentials</span><span class=\"mtk1\">(</span><span class=\"mtk12\">credentials</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const </span><span class=\"mtk12\">userProfile</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">userService</span><span class=\"mtk1\">.</span><span class=\"mtk11\">convertToUserProfile</span><span class=\"mtk1\">(</span><span class=\"mtk12\">user</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const </span><span class=\"mtk12\">token</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">jwtService</span><span class=\"mtk1\">.</span><span class=\"mtk11\">generateToken</span><span class=\"mtk1\">(</span><span class=\"mtk12\">userProfile</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      return { </span><span class=\"mtk12\">token</span><span class=\"mtk1\"> };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span></code></pre>\n<p>Perhaps, you can show the currently logged-in user by adding a <code>/whoami</code> endpoint.</p>\n<p>In the <code>src/controllers/user.controller.ts</code> file, get the details of the currently logged-in user using the code snippet below. Users should access this endpoint only when they are logged in.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"16\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">authenticate</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;jwt&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/whoami&#39;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">responses:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk8\">&#39;200&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">description:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;Return current user&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">content:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">schema:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                  </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;string&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">whoAmI</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        @</span><span class=\"mtk11\">inject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">SecurityBindings</span><span class=\"mtk1\">.</span><span class=\"mtk12\">USER</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">loggedInUserProfile</span><span class=\"mtk1\">: </span><span class=\"mtk12\">UserProfile</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      ): </span><span class=\"mtk10\">Promise</span><span class=\"mtk1\">&lt;</span><span class=\"mtk12\">string</span><span class=\"mtk1\">&gt; {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        return loggedInUserProfile</span><span class=\"mtk12\">[securityId];</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">      }</span></span></code></pre>\n<p>Now, open <code>src/application.ts</code> and bind the authentication components to your application class. First, import Loopback <code>AuthenticationComponent</code>, <code>JWTAuthenticationComponent</code>, and <code>NewsDataSource</code> from your <code>datasources</code> using the following code snippet:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"17\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">//...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">AuthenticationComponent</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@loopback/authentication&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">JWTAuthenticationComponent</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">UserServiceBindings</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">} </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@loopback/authentication-jwt&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">NewsDataSource</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./datasources&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//...</span></span></code></pre>\n<p>Then, mount the jwt authentication system and bind your <code>NewsDataSource</code> to the <code>UserService</code> data source.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"18\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">//...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// ------ ADD SNIPPET INSIDE THE CONTRUCTOR BLOCK ---------</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">component</span><span class=\"mtk1\">(</span><span class=\"mtk12\">AuthenticationComponent</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">component</span><span class=\"mtk1\">(</span><span class=\"mtk12\">JWTAuthenticationComponent</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">dataSource</span><span class=\"mtk1\">(</span><span class=\"mtk12\">NewsDataSource</span><span class=\"mtk1\">, </span><span class=\"mtk12\">UserServiceBindings</span><span class=\"mtk1\">.</span><span class=\"mtk12\">DATASOURCE_NAME</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//...</span></span></code></pre>\n<p>Finally, add the authenticate action in the Sequence. Also, modify the error when authentication fails to return status code 401 (Unauthorized). Open the <code>src/sequence.ts</code> file and add the code snippet below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"19\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">FindRoute</span><span class=\"mtk1\">, </span><span class=\"mtk12\">InvokeMethod</span><span class=\"mtk1\">, </span><span class=\"mtk12\">MiddlewareSequence</span><span class=\"mtk1\">, </span><span class=\"mtk12\">ParseParams</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Reject</span><span class=\"mtk1\">, </span><span class=\"mtk12\">RequestContext</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Send</span><span class=\"mtk1\">, </span><span class=\"mtk12\">SequenceActions</span><span class=\"mtk1\">, </span><span class=\"mtk12\">SequenceHandler</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@loopback/rest&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">AuthenticateFn</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">AuthenticationBindings</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">AUTHENTICATION_STRATEGY_NOT_FOUND</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">USER_PROFILE_NOT_FOUND</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@loopback/authentication&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">inject</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@loopback/core&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">MySequence</span><span class=\"mtk1\"> </span><span class=\"mtk4\">implements</span><span class=\"mtk1\"> </span><span class=\"mtk10\">SequenceHandler</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            @</span><span class=\"mtk11\">inject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">SequenceActions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">FIND_ROUTE</span><span class=\"mtk1\">) </span><span class=\"mtk4\">protected</span><span class=\"mtk1\"> </span><span class=\"mtk12\">findRoute</span><span class=\"mtk1\">: </span><span class=\"mtk10\">FindRoute</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            @</span><span class=\"mtk11\">inject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">SequenceActions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">PARSE_PARAMS</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">protected</span><span class=\"mtk1\"> </span><span class=\"mtk12\">parseParams</span><span class=\"mtk1\">: </span><span class=\"mtk10\">ParseParams</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            @</span><span class=\"mtk11\">inject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">SequenceActions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">INVOKE_METHOD</span><span class=\"mtk1\">) </span><span class=\"mtk4\">protected</span><span class=\"mtk1\"> </span><span class=\"mtk12\">invoke</span><span class=\"mtk1\">: </span><span class=\"mtk10\">InvokeMethod</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            @</span><span class=\"mtk11\">inject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">SequenceActions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">SEND</span><span class=\"mtk1\">) </span><span class=\"mtk4\">protected</span><span class=\"mtk1\"> </span><span class=\"mtk12\">send</span><span class=\"mtk1\">: </span><span class=\"mtk10\">Send</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            @</span><span class=\"mtk11\">inject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">SequenceActions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">REJECT</span><span class=\"mtk1\">) </span><span class=\"mtk4\">protected</span><span class=\"mtk1\"> </span><span class=\"mtk12\">reject</span><span class=\"mtk1\">: </span><span class=\"mtk10\">Reject</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            @</span><span class=\"mtk11\">inject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">AuthenticationBindings</span><span class=\"mtk1\">.</span><span class=\"mtk12\">AUTH_ACTION</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">protected</span><span class=\"mtk1\"> </span><span class=\"mtk12\">authenticateRequest</span><span class=\"mtk1\">: </span><span class=\"mtk10\">AuthenticateFn</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        ) { }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">handle</span><span class=\"mtk1\">(</span><span class=\"mtk12\">context</span><span class=\"mtk1\">: </span><span class=\"mtk10\">RequestContext</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">try</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">request</span><span class=\"mtk1\">, </span><span class=\"mtk12\">response</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">context</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">route</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">findRoute</span><span class=\"mtk1\">(</span><span class=\"mtk12\">request</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk3\">//call authentication action</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">authenticateRequest</span><span class=\"mtk1\">(</span><span class=\"mtk12\">request</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk3\">// Authentication successful, proceed to invoke controller</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">args</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">parseParams</span><span class=\"mtk1\">(</span><span class=\"mtk12\">request</span><span class=\"mtk1\">, </span><span class=\"mtk12\">route</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">invoke</span><span class=\"mtk1\">(</span><span class=\"mtk12\">route</span><span class=\"mtk1\">, </span><span class=\"mtk12\">args</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">send</span><span class=\"mtk1\">(</span><span class=\"mtk12\">response</span><span class=\"mtk1\">, </span><span class=\"mtk12\">result</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            } </span><span class=\"mtk15\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">code</span><span class=\"mtk1\"> === </span><span class=\"mtk12\">AUTHENTICATION_STRATEGY_NOT_FOUND</span><span class=\"mtk1\"> ||</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">code</span><span class=\"mtk1\"> === </span><span class=\"mtk12\">USER_PROFILE_NOT_FOUND</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                ) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk10\">Object</span><span class=\"mtk1\">.</span><span class=\"mtk11\">assign</span><span class=\"mtk1\">(</span><span class=\"mtk12\">error</span><span class=\"mtk1\">, { </span><span class=\"mtk12\">statusCode:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">401</span><span class=\"mtk3\">/* Unauthorized */</span><span class=\"mtk1\"> });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">reject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">context</span><span class=\"mtk1\">, </span><span class=\"mtk12\">error</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">return</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span></code></pre>\n<h2 id=\"protect-news-endpoints\" style=\"position:relative;\"><a href=\"#protect-news-endpoints\" aria-label=\"protect news endpoints permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Protect News Endpoints</h2>\n<p>So far, you've implemented user authentication for your API. Now, protect your News endpoints so that only authenticated users can access those routes.</p>\n<p>Open the <code>src/controllers/news.controller.ts</code> file, and import <code>authenticate</code> from jwt authentication.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"20\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">authenticate</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@loopback/authentication&quot;</span></span></code></pre>\n<p>Then on each of the endpoints in your news controller, add <code>@authenticate('jwt')</code> before the <code>NewsController</code> class, which will protect all the routes in <code>NewsController</code>.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"21\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">//...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    @</span><span class=\"mtk11\">authenticate</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;jwt&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">//...</span></span></code></pre>\n<p>Perhaps, you may not want to protect all the routes, simply add the <code>@authenticate('jwt')</code> method before the route you wish to protect. You can protect the POST route as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"22\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    @</span><span class=\"mtk11\">authenticate</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;jwt&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    @</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/news-models&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">response</span><span class=\"mtk1\">(</span><span class=\"mtk7\">200</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">description:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;NewsModel model instance&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">content:</span><span class=\"mtk1\"> { </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">schema:</span><span class=\"mtk1\"> </span><span class=\"mtk11\">getModelSchemaRef</span><span class=\"mtk1\">(</span><span class=\"mtk12\">NewsModel</span><span class=\"mtk1\">) } },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">create</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        @</span><span class=\"mtk11\">requestBody</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">content:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">schema:</span><span class=\"mtk1\"> </span><span class=\"mtk11\">getModelSchemaRef</span><span class=\"mtk1\">(</span><span class=\"mtk12\">NewsModel</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">title:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;NewNewsModel&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">exclude:</span><span class=\"mtk1\"> [</span><span class=\"mtk8\">&#39;id&#39;</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              }),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">newsModel</span><span class=\"mtk1\">: </span><span class=\"mtk12\">Omit</span><span class=\"mtk1\">&lt;</span><span class=\"mtk12\">NewsModel</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;id&#39;</span><span class=\"mtk1\">&gt;,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      ): </span><span class=\"mtk10\">Promise</span><span class=\"mtk1\">&lt;</span><span class=\"mtk12\">NewsModel</span><span class=\"mtk1\">&gt; {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        return this.newsModelRepository.create(newsModel);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      }</span></span></code></pre>\n<h2 id=\"test-your-application\" style=\"position:relative;\"><a href=\"#test-your-application\" aria-label=\"test your application permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test Your Application</h2>\n<p>You've implemented user authentication in your REST API and secured the routes against unauthorized users. Let's put your application to the test. Press <code>CTRL-C</code> to exit the server and restart it with the following command:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"23\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    npm start</span></span></code></pre>\n<p>If you open the explorer page, you should see the <code>UserController</code> endpoints.</p>\n<p><img src=\"/1f93015b74e330c7dd57e99d9145a9d8/IaV4R43g.webp\" alt=\"User Controller Endpoints\"></p>\n<p>If you try to execute any query on <code>NewsController</code>, you get a 404 (Unauthorized) error. So, sign up by clicking the <code>/signup</code> endpoint — and log in from the <code>/users/login</code> endpoint. On successful login, copy the token, scroll to the top, click on the <code>Authorize</code> button, and paste the token.</p>\n<p><img src=\"/3308ca6960b64dab62adf3646b42032a/atU6nqmA.webp\" alt=\"Authorizing Users\"></p>\n<p>Now you can execute queries on the <code>NewController</code> endpoints.</p>\n<h2 id=\"user-authentication-with-loginradius\" style=\"position:relative;\"><a href=\"#user-authentication-with-loginradius\" aria-label=\"user authentication with loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>User Authentication with Loginradius</h2>\n<p>LoginRadius is a customer identity and access management (CIAM) platform for developers.</p>\n<p>What does this mean for developers like you?</p>\n<p>LoginRadius simplifies the process of user authentication, authorization, and management across web and mobile apps and APIs. It helps developers quickly implement this functionality so that developers, like you, can focus more on building core features that are essential to their apps.</p>\n<p>Loginradius includes a plethora of enticing CIAM features such as passwordless authentication and social SSO (Twitter, Facebook, etc., based single sign-on).</p>\n<p>Implementing user authentication with LoginRadius is a simple procedure. First, sign up for a Developer Pro trial or simply <a href=\"https://accounts.loginradius.com/auth.aspx?action=register\">sign up for a forever free account here</a>.</p>\n<p>And you can explore what LoginRadius can do by using it for a Node.js application. You can learn more by going through <a href=\"https://www.loginradius.com/developers/\">LoginRadius Node.js developer documentation</a></p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>This tutorial taught you how to create user authentication in a LoopBack REST API by creating a small news database application.</p>\n<p>You can use the steps outlined in this tutorial to create any type of LoopBack REST API that requires user authentication and authorization.</p>\n<p>I hope you enjoyed this tutorial! Feel free to contact me on <a href=\"https://twitter.com/EkekentaZion\">Twitter</a>.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n</style>","frontmatter":{"date":"February 04, 2022","updated_date":null,"description":"Are you building dynamic REST APIs with LoopBack? In this tutorial, you'll learn how to implement user authentication and authorization in a Loopback REST API.","title":"How to Secure Your LoopBack REST API with JWT Authentication","tags":["Authentication","LoopBack","JWT","Node.js"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/4a5b6d544acaf9e9a42893f7df9dd057/58556/secure-loopback-rest-api-with-jwt.webp","srcSet":"/static/4a5b6d544acaf9e9a42893f7df9dd057/61e93/secure-loopback-rest-api-with-jwt.webp 200w,\n/static/4a5b6d544acaf9e9a42893f7df9dd057/1f5c5/secure-loopback-rest-api-with-jwt.webp 400w,\n/static/4a5b6d544acaf9e9a42893f7df9dd057/58556/secure-loopback-rest-api-with-jwt.webp 800w,\n/static/4a5b6d544acaf9e9a42893f7df9dd057/99238/secure-loopback-rest-api-with-jwt.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Ekekenta Odionyenfe Clinton","github":"icode247","avatar":null}}}},{"node":{"excerpt":"Authentication remains at the core of any application with user data and accounts. It ensures that only the authorized person is accessing…","fields":{"slug":"/engineering/developers-can-get-rid-of-password-based-authentication/"},"html":"<p>Authentication remains at the core of any application with user data and accounts. It ensures that only the authorized person is accessing the data and account. So far, Password-based authentication has been prevalent that developers mostly use.</p>\n<p>Unfortunately, passwords are no longer a wise choice for developers to ensure secure and seamless authentication. Let’s see why:</p>\n<ul>\n<li><strong>Vulnerable to cyberattacks:</strong> Passwords are still used as an authentication mechanism because of the long-standing efforts developers and technology industry leaders are delivering to secure the passwords. But hackers are in constant pursuit to breach passwords through different cyber-attacks and as a result, nearly 1 million passwords get stolen each week.</li>\n<li><strong>Security is subjected to chosen passwords:</strong> Users tend to use repetitive or insecure passwords for their accounts, which weakens the authentication security. If a user's password is leaked in one breach, it can impact the security of other applications where the user is using the same password.</li>\n<li><strong>Easily forgotten by users:</strong> Considering the risks password-based authentication poses to an application, developers need to include password policies and enforce restrictive logic in their authentication algorithms to accept strong passwords. This makes it even more difficult for the user to remember their account password. Such setup results in higher forgotten password requests requiring more development and support resources.</li>\n<li><strong>Efforts in securing and managing password-based authentication:</strong> Password policies, security algorithms, encryption techniques have become minimal viable requirements to manage password-based authentication. This increases the development efforts involved in developing and managing password-based authentication.</li>\n</ul>\n<p>Before talking about the solution in detail, let’s get deeper into the problem and see what are the common cyber-attacks faced by password-based authentication.</p>\n<h2 id=\"common-cyber-attacks-with-password-based-authentication\" style=\"position:relative;\"><a href=\"#common-cyber-attacks-with-password-based-authentication\" aria-label=\"common cyber attacks with password based authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Common Cyber-attacks with Password-based Authentication</h2>\n<p>The following is the list of common password attacks. It also explains what additional efforts developers need to put in to fight these cyber-attacks and protect user data:</p>\n<ul>\n<li><strong>Brute force:</strong> This password cracking attack use automation to guess a password millions of times. It tries all the possible combinations and permutations of passwords to exploit weak passwords like abcd@9876.</li>\n</ul>\n<p>To protect against this attack, developers have to develop security features like suspending or locking user accounts on multiple subsequent attempts to log in with an incorrect password.</p>\n<ul>\n<li><strong>Credential Stuffing:</strong> It is a type of identity theft where the attacker injects breached or leaked credentials of one account to access numerous other user accounts.</li>\n</ul>\n<p>To protect against this attack, developers have to ensure that users are not using insecure or previously breached passwords.</p>\n<ul>\n<li><strong>Keylogging:</strong> It records the user's keyboard interactions and key presses. Keylogger programs are used to record what users are typing on their keyboard and send the logged data to the creator.</li>\n</ul>\n<p>To protect against this attack, developers need to introduce 2FA (two-factor authentication). Stakes are high in this case as a lot depends on how users take security measures.</p>\n<ul>\n<li><strong>Man-in-the-Middle (MiTM):</strong> In this type of attack, the attacker sits in between the target user and the web application and deciphers all traffic passed among each other such as username, passwords, etc.</li>\n</ul>\n<p>That is where developers have to be cautious, keeping all the data-in-transit encrypted.</p>\n<p>Luckily getting rid of passwords from the authentication mechanism can address all the above-stated problems. Eliminating passwords from internet space is certainly not a 1-day thing, but the responsibility lies with developers.</p>\n<p>Developers should introduce more secure and user-friendly authentication methods to their application users such as magic links, single sign-on (SSO), biometric, hardware-based authentication.</p>\n<h2 id=\"alternatives-to-password-based-authentication\" style=\"position:relative;\"><a href=\"#alternatives-to-password-based-authentication\" aria-label=\"alternatives to password based authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Alternatives to Password-based Authentication</h2>\n<h3 id=\"passwordless-authentication\" style=\"position:relative;\"><a href=\"#passwordless-authentication\" aria-label=\"passwordless authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Passwordless Authentication</h3>\n<p>It does the user authentication based on the \"possession factor.\" That is where developers find passwordless authentication trustworthy, as the authentication uses a phone number, email ID, or authenticator app to cater to an OTP, one-time link, or code respectively to verify the user.</p>\n<p>Through this, developers can improve the user experience of the application and reduce risk while minimizing the total cost of storing the login credentials. Users will employ the one-time link or OTP only if they are logged into their email or possess the phone for SMS. This assures the developer a better security.</p>\n<h3 id=\"single-sign-on\" style=\"position:relative;\"><a href=\"#single-sign-on\" aria-label=\"single sign on permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Single Sign-on</h3>\n<p>Almost all websites demand some form of authentication to access their content and features. Single sign-on authentication has become a standard authentication method for website logins.</p>\n<p>Developers can integrate the single sign-on feature in their web applications to facilitate users to securely authenticate multiple apps and websites by leveraging one set of login credentials.</p>\n<p>Through SSO, developers can implement multi-factor authentication implicitly. It uses a federated identity management architecture that relies on open standard protocols to exchange identity and authentication information among these protocols. That makes implementing the security easier for developers.</p>\n<h3 id=\"biometric-authentication\" style=\"position:relative;\"><a href=\"#biometric-authentication\" aria-label=\"biometric authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Biometric Authentication</h3>\n<p>Biometrics refers to the user's physical characteristics allowing them to identify uniquely on a digital platform. Instead of typing letters, numbers, and symbols (for passwords), biometric authentication uses biometric systems to calculate and estimate the user's physical attributes. Facial recognition, tiny impressions made by fingerprints, and vocal cadence are well-known biometric authentication techniques.</p>\n<p>It is gaining traction because developers do not have to maintain a separate database of usernames and passwords since the authentication takes place from the user device rather than the application's database.</p>\n<h3 id=\"smart-authentication\" style=\"position:relative;\"><a href=\"#smart-authentication\" aria-label=\"smart authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Smart Authentication</h3>\n<p>Most in-house developers and smart device vendors leverage this authentication technique to avoid password authentication. This authentication mostly uses QR codes or link-based login approaches. Here the one-time link or the QR code uniquely generates the verification process that helps initiate the user login process without any password.</p>\n<h3 id=\"hardware-based-authentication\" style=\"position:relative;\"><a href=\"#hardware-based-authentication\" aria-label=\"hardware based authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Hardware-based authentication</h3>\n<p>In this approach, the authentication uses a dedicated plug-and-run physical device belonging to the authorized user. These versatile security devices help users log in to desktops, Wi-Fi, websites, and other applications.</p>\n<p>FIDO2 devices are touch-sensed USB sticks that enable hardware authentication and follow the FIDO Alliance standards and specifications. Leveraging this authentication mechanism is a plus point as the developers do not have to maintain a secure database for the login credentials.</p>\n<h2 id=\"can-we-actually-get-rid-of-passwords\" style=\"position:relative;\"><a href=\"#can-we-actually-get-rid-of-passwords\" aria-label=\"can we actually get rid of passwords permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Can we actually get rid of passwords?</h2>\n<p>For decades, password-based authentication has been the mainstay for security and user verification. On average, almost all online users have 20 to 30 login credentials for different applications and sites. Password logins have become so common that changing the authentication trend and adopting a new authentication approach will take time.</p>\n<p>All the alternatives mentioned in this article can help minimize using passwords to a significant level. It's time developers should seriously ponder the problems that passwords can create for themselves and opt for reasonable alternatives as per the situation, requirements, or policy standards.</p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>Passwords are becoming more like a liability rather than a security asset. Hence, to get rid of them, developers are leveraging other means of authentication that are more reliable and less susceptible to security breaches and threats.</p>\n<p>Worried about efforts involved in implementing these alternative authentication methods from scratch? <a href=\"https://accounts.loginradius.com/auth.aspx?action=register&#x26;return_url=https://dashboard.loginradius.com/login&#x26;plan=pro\">LoginRadius</a> identity platform comes with these authentication techniques so that developers do not have to implement them from scratch in their applications to provide alternate authentication.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"January 31, 2022","updated_date":null,"description":"Authentication remains at the core of any application with user data and accounts. It ensures that only the authorized person is accessing the data and account. So far, Password-based authentication has been prevalent that developers mostly use.","title":"When Can Developers Get Rid of Password-based Authentication?","tags":["Authentication"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/c9cb7d184cd59f1d58470baae77763e1/58556/password-dev.webp","srcSet":"/static/c9cb7d184cd59f1d58470baae77763e1/61e93/password-dev.webp 200w,\n/static/c9cb7d184cd59f1d58470baae77763e1/1f5c5/password-dev.webp 400w,\n/static/c9cb7d184cd59f1d58470baae77763e1/58556/password-dev.webp 800w,\n/static/c9cb7d184cd59f1d58470baae77763e1/99238/password-dev.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Kundan Singh","github":null,"avatar":null}}}},{"node":{"excerpt":"BigCommerce is a great eCommerce platform with rich features, and millions of people benefit from it. But there are limitations when you…","fields":{"slug":"/engineering/extend-ciam-capabilities-of-bigcommerce/"},"html":"<p>BigCommerce is a great eCommerce platform with rich features, and millions of people benefit from it. But there are limitations when you want to extend the platform for the following identity and access management requirements:</p>\n<ul>\n<li><strong>Single sign-on (SSO)</strong> to enhance the user experience and improve authentication security</li>\n<li><strong>Phone login</strong> via mobile number and OTP for quick customer sign-up and sign-in</li>\n<li><strong>Prefilled customer information</strong> via Social Login for easy checkout</li>\n<li><strong>Analytics</strong> to learn more about individual customers to boost upsell and cross-sell</li>\n</ul>\n<p>Let’s talk about how you can extend BigCommerce and add on the above-mentioned features hassle-free.</p>\n<p>The answer is to utilize a <strong>CIAM</strong> (Consumer Identity and Access Management) that provides BigCommerce integration. You can easily configure and implement these features with minimal development effort using the CIAM provider. One such CIAM provider is <a href=\"https://accounts.loginradius.com/auth.aspx?return_url=https://dashboard.loginradius.com/login&#x26;action=register&#x26;plan=pro\">LoginRadius</a>.</p>\n<h2 id=\"how-to-implement-these-features\" style=\"position:relative;\"><a href=\"#how-to-implement-these-features\" aria-label=\"how to implement these features permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to Implement These Features</h2>\n<p>You are required to create an account with the CIAM provider, enable BigCommerce Integration, and do needed configurations in both BigCommerce and CIAM Provider. For more details, refer to this guide <a href=\"https://www.loginradius.com/developers/\">here</a>.\nThis guide also explains the modifications required in your Stencil or Blueprint themes of BigCommerce. As a result of this implementation, you can enable the desired authentication method(s) for customers of your BigCommerce Application. Consequently, making the eCommerce experience smoother for your customers.</p>\n<p>Both customer and business will see several benefits (described below) from using CIAM solutions for features such as SSO, Phone Login, Prefilled Customer Information, and Analytics.</p>\n<h2 id=\"benefits-of-implementing-these-features\" style=\"position:relative;\"><a href=\"#benefits-of-implementing-these-features\" aria-label=\"benefits of implementing these features permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Benefits of Implementing These Features</h2>\n<h3 id=\"enhanced-customer-experience-with-sso\" style=\"position:relative;\"><a href=\"#enhanced-customer-experience-with-sso\" aria-label=\"enhanced customer experience with sso permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Enhanced Customer Experience with SSO</h3>\n<p>SSO lets customers log in with an existing identity. Allowing customers to use their existing identity increases conversions and return rates. It also improves security by allowing your customers to manage lesser digital identities and credentials.\nThe movement toward Bring Your Own Identity(BYOI) is gaining prominence as customers look to control their digital profiles, and SSO enables customers to bring their own digital identity.</p>\n<h3 id=\"increased-customer-engagement-with-phone-login\" style=\"position:relative;\"><a href=\"#increased-customer-engagement-with-phone-login\" aria-label=\"increased customer engagement with phone login permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Increased Customer Engagement with Phone Login</h3>\n<p>Phone login via OTP allows customers to easily log into their account without remembering a username or password. They only need to provide the Phone Number and then enter the received OTP to log in.</p>\n<p>This process makes sign-up and sign-in seamless for the customers and improves customer engagement. Also, businesses get fewer or no forgot password requests from customers, which reduces the support efforts.</p>\n<h3 id=\"improved-upsell-and-cross-sell-with-prefilled-information\" style=\"position:relative;\"><a href=\"#improved-upsell-and-cross-sell-with-prefilled-information\" aria-label=\"improved upsell and cross sell with prefilled information permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Improved Upsell and Cross-sell with Prefilled Information</h3>\n<p>The top reason behind the cart abandonment is the long or confusing checkout process. Using the prefilled customer information with the LoginRadius Social Login feature, you can reduce the overall time involved in the checkout process.</p>\n<p>Prefilled customer information such as name, city, email address during checkout allows customers to place orders quickly.</p>\n<p>Let’s say a customer logged in using a social account and during checkout. With the customer’s permission, LoginRadius can retrieve basic information like name, email, birth date, gender from their social account. Thus, the customers need not enter data manually and experience a shorter and smoother checkout process.</p>\n<h3 id=\"insights-turned-into-actions\" style=\"position:relative;\"><a href=\"#insights-turned-into-actions\" aria-label=\"insights turned into actions permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Insights Turned into Actions</h3>\n<p>When you use LoginRadius as CIAM, it stores your customer data with your desired data centers. Also, LoginRadius Dashboard allows you to access the customer analytics related to identity, demographics, login, communication, etc. These analytics and charts help you understand your customers and their preferences better.</p>\n<p>For example:</p>\n<ul>\n<li>Login medium(s) popular with your customers</li>\n<li>Age groups and areas where your products are purchased the most</li>\n</ul>\n<p>In addition to the benefits mentioned above, you experience below additional benefits:</p>\n<ul>\n<li>Implement all the above-stated features with minimal development efforts or customizations at your end.</li>\n<li>Seamlessly manage any B2B access and communication to manage the eCommerce business effortlessly.</li>\n</ul>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>Extending the capabilities of your great eCommerce platform is like a cherry on the cake. <a href=\"https://accounts.loginradius.com/auth.aspx?action=register&#x26;return_url=https://dashboard.loginradius.com/login\">Signup for free</a> and get in touch with us to take your eCommerce platform a level ahead.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"January 27, 2022","updated_date":null,"description":"Want to add Phone Login or Single Sign-on for customers of your BigCommerce application? This article explains it all. Towards the end, it talks about how LoginRadius can help you improve upsell and cross-sell.","title":"4 Ways to Extend CIAM Capabilities of BigCommerce","tags":["BigCommerce","Authentication","CIAM"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/8c9fb8572282ac70e1a960bc7c47ec2b/58556/4-ways-to-extend-ciam-capabilities.webp","srcSet":"/static/8c9fb8572282ac70e1a960bc7c47ec2b/61e93/4-ways-to-extend-ciam-capabilities.webp 200w,\n/static/8c9fb8572282ac70e1a960bc7c47ec2b/1f5c5/4-ways-to-extend-ciam-capabilities.webp 400w,\n/static/8c9fb8572282ac70e1a960bc7c47ec2b/58556/4-ways-to-extend-ciam-capabilities.webp 800w,\n/static/8c9fb8572282ac70e1a960bc7c47ec2b/99238/4-ways-to-extend-ciam-capabilities.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Archna Yadav","github":null,"avatar":null}}}},{"node":{"excerpt":"Introduction Creating a user registration form employs the management of the registered user. This is where user role authentication comes…","fields":{"slug":"/engineering/guest-post/nodejs-authentication-guide/"},"html":"<h2 id=\"introduction\" style=\"position:relative;\"><a href=\"#introduction\" aria-label=\"introduction permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Introduction</h2>\n<p>Creating a user registration form employs the management of the registered user. This is where user role authentication comes into play. Role authentication ensures that non-admin users cannot make changes or access exclusive information. It grants administrative privileges to admin users and basic privileges to basic users.</p>\n<p>You can build your own authentication functionality with web tokens like JSON Web Token (JWT) or use a trusted third-party customer identity and access management (CIAM) software like LoginRadius.</p>\n<h2 id=\"goal\" style=\"position:relative;\"><a href=\"#goal\" aria-label=\"goal permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Goal</h2>\n<p>This tutorial helps you:</p>\n<ul>\n<li>understand the differences between the Admin role and the Basic user role;</li>\n<li>use JWT to authenticate users; and</li>\n<li>learn role-based authentication using JWT in a simple Node.js app.</li>\n</ul>\n<h2 id=\"prerequisites\" style=\"position:relative;\"><a href=\"#prerequisites\" aria-label=\"prerequisites permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Prerequisites</h2>\n<p>You have installed the following:</p>\n<ul>\n<li><a href=\"https://nodejs.org/en/download/\">Node</a></li>\n<li><a href=\"https://www.mongodb.com/try/download/community\">MongoDB</a></li>\n<li>a <a href=\"https://code.visualstudio.com/download\">Text Editor</a></li>\n</ul>\n<p>You already understand JavaScript <a href=\"https://www.w3schools.com/js/js_es6.asp\">E56 Syntax</a>.</p>\n<p>Now that everything is in place, let's set up your database.</p>\n<h2 id=\"set-up-a-mongo-database\" style=\"position:relative;\"><a href=\"#set-up-a-mongo-database\" aria-label=\"set up a mongo database permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Set Up a Mongo Database</h2>\n<p>You'll store all your user data — which includes username, password, and role — in MongoDB.</p>\n<p>Install a node package called Mongoose that will connect to MongoDB. Then create a user <code>schema</code> for your application.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">npm</span><span class=\"mtk1\"> </span><span class=\"mtk12\">init</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">npm</span><span class=\"mtk1\"> </span><span class=\"mtk12\">install</span><span class=\"mtk1\"> </span><span class=\"mtk12\">mongoose</span></span></code></pre>\n<p><code>npm init</code> sets up your new project and creates a <code>package.json</code> file with the credentials.</p>\n<p>After installing mongoose, create a new file <code>db.js</code> in the project's directory and require <code>mongoose</code>.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Mongoose</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;mongoose&quot;</span><span class=\"mtk1\">)</span></span></code></pre>\n<p>With the help of mongoose, you can connect your application to MongoDB:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">// db.js</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Mongoose</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;mongoose&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">localDB</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">`mongodb://localhost:27017/role_auth`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">connectDB</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Mongoose</span><span class=\"mtk1\">.</span><span class=\"mtk11\">connect</span><span class=\"mtk1\">(</span><span class=\"mtk12\">localDB</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">useNewUrlParser:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">useUnifiedTopology:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;MongoDB Connected&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">module</span><span class=\"mtk1\">.</span><span class=\"mtk10\">exports</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">connectDB</span></span></code></pre>\n<p>The code snippet here connects to <code>mongodb://localhost:27017</code> and then specifies the name of the database <code>/role_auth</code>.</p>\n<p>The function <code>connectDB</code> awaits for the connection, which contains the <code>URI</code> and <code>options</code> as a second parameter. If it connects without errors, it will log out <code>MongoDB Connected</code>. Error issues will be fixed while connecting to the database. After this, it exported the function for use in the server.</p>\n<h2 id=\"set-up-the-server\" style=\"position:relative;\"><a href=\"#set-up-the-server\" aria-label=\"set up the server permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Set Up the Server</h2>\n<p>You need to install some dependencies that you'll use in this tutorial.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">npm</span><span class=\"mtk1\"> </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> </span><span class=\"mtk12\">express</span><span class=\"mtk1\"> </span><span class=\"mtk12\">nodemon</span></span></code></pre>\n<p><a href=\"https://expressjs.com/\">Express.js</a> is a Node.js framework for building web applications quickly and easily.</p>\n<p><a href=\"https://www.npmjs.com/package/nodemon\">Nodemon</a> is a tool that watches the file system and automatically restarts the server when there is a change.</p>\n<p>You require <code>express</code> in your application to listen for a connection on port <code>5000</code>. Create a new file <code>server.js</code> in the root directory and create the listening event:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">express</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;express&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">app</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">express</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">PORT</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">5000</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">listen</span><span class=\"mtk1\">(</span><span class=\"mtk12\">PORT</span><span class=\"mtk1\">, () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">`Server Connected to port </span><span class=\"mtk4\">${</span><span class=\"mtk12\">PORT</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span><span class=\"mtk1\">))</span></span></code></pre>\n<p>The next step is to test your application. Open up your <code>package.json</code> file and add the following to <code>scripts</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"json\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk8\">&quot;scripts&quot;</span><span class=\"mtk1\">: {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">&quot;start&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;node server.js&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">&quot;dev&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;nodemon server.js&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Open your terminal and run <code>npm run dev</code> to start the server.</p>\n<h2 id=\"connect-to-the-database\" style=\"position:relative;\"><a href=\"#connect-to-the-database\" aria-label=\"connect to the database permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Connect to the Database</h2>\n<p>Earlier, you've created a function that connects to MongoDB and exported that function. Now import that function into your <code>server.js</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">connectDB</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;./db&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//Connecting the Database</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">connectDB</span><span class=\"mtk1\">();</span></span></code></pre>\n<p>You also need to create an error handler that catches every <code>unhandledRejection</code> error.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">server</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">listen</span><span class=\"mtk1\">(</span><span class=\"mtk12\">PORT</span><span class=\"mtk1\">, () </span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">`Server Connected to port </span><span class=\"mtk4\">${</span><span class=\"mtk12\">PORT</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// Handling Error</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">process</span><span class=\"mtk1\">.</span><span class=\"mtk11\">on</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;unhandledRejection&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">err</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">`An error occurred: </span><span class=\"mtk4\">${</span><span class=\"mtk12\">err</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">server</span><span class=\"mtk1\">.</span><span class=\"mtk11\">close</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">process</span><span class=\"mtk1\">.</span><span class=\"mtk11\">exit</span><span class=\"mtk1\">(</span><span class=\"mtk7\">1</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span></code></pre>\n<p>The listening event is assigned to a constant <code>server</code>. If an <code>unhandledRejection</code> error occurs, it logs out the error and closes the <code>server</code> with an exit code of 1.</p>\n<h2 id=\"create-user-schema\" style=\"position:relative;\"><a href=\"#create-user-schema\" aria-label=\"create user schema permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create User Schema</h2>\n<p><a href=\"https://en.wikipedia.org/wiki/Database_schema\">Schema</a> is like a blueprint that shows how the database will be constructed.</p>\n<p>You'll structure a user schema that contains username, password, and role.</p>\n<p>Create a new folder <code>model</code> in the project's directory, and create a file called <code>User.js</code>. Now open <code>User.js</code> and create the user schema:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">// user.js</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Mongoose</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;mongoose&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">UserSchema</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Mongoose</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Schema</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">String</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">unique:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">required:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">String</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">minlength:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">6</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">required:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">role:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">String</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">default:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Basic&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">required:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span></code></pre>\n<p>In the schema, the <code>username</code> will be unique, required, and will accept <code>strings</code>.</p>\n<p>You've specified the minimum characters(6) the <code>password</code> field will accept. The <code>role</code> field grants a default value (basic) that you can change if needed.</p>\n<p>Now, you need to create a user model and export it:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">Mongoose</span><span class=\"mtk1\">.</span><span class=\"mtk11\">model</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;user&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">UserSchema</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">module</span><span class=\"mtk1\">.</span><span class=\"mtk10\">exports</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">User</span></span></code></pre>\n<p>You've created the user model by passing the <code>UserSchema</code> as the second argument while the first argument is the name of the model <code>user</code>.</p>\n<h2 id=\"perform-crud-operations\" style=\"position:relative;\"><a href=\"#perform-crud-operations\" aria-label=\"perform crud operations permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Perform CRUD Operations</h2>\n<p>You'll create functions that handle:</p>\n<ul>\n<li>adding users;</li>\n<li>getting all users;</li>\n<li>updating the role of users; and,</li>\n<li>deleting users.</li>\n</ul>\n<h3 id=\"register-function\" style=\"position:relative;\"><a href=\"#register-function\" aria-label=\"register function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Register Function</h3>\n<p>As the name implies, this function will handle the registrations of users.</p>\n<p>Let's create a new folder named <code>Auth</code>. It will contain the Authentication file and the Route set-up file.</p>\n<p>After creating the <code>Auth</code> folder, add two files — <code>Auth.js</code> and <code>Route.js</code>.</p>\n<p>Now open up our <code>Auth.js</code> file and import that <code>User</code> model:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;../model/User&quot;</span><span class=\"mtk1\">)</span></span></code></pre>\n<p>The next step is to create an <code>async</code> <code>express</code> function that will take the user's data and register it in the database.</p>\n<p>You need to use an <a href=\"https://expressjs.com/en/guide/writing-middleware.html\">Express middleware</a> function that will grant access to the user's data from the body. You'll use this function in the <code>server.js</code> file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">app</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">express</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk12\">express</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">())</span></span></code></pre>\n<p>Let's go back to your <code>Auth.js</code> file and create the register function:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"12\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">// auth.js</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">register</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">password</span><span class=\"mtk1\">.</span><span class=\"mtk12\">length</span><span class=\"mtk1\"> &lt; </span><span class=\"mtk7\">6</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Password less than 6 characters&quot;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">try</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\">.</span><span class=\"mtk11\">create</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">username</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">password</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }).</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">user</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">200</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User successfully created&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">user</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User not successful created&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">mesage</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The exported <code>register</code> function will be used to set up the routes. You got the username and password from the <code>req.body</code> and created a <code>tryCatch</code> block that will create the user if successful; else, it returns status code <code>401</code> with the error message.</p>\n<h3 id=\"set-up-register-route\" style=\"position:relative;\"><a href=\"#set-up-register-route\" aria-label=\"set up register route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Set Up Register Route</h3>\n<p>You'll create a route to <code>/register</code> using <code>express.Router</code>. Import the <code>register</code> function into your <code>route.js</code> file, and use it as the route's function:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"13\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">express</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;express&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">express</span><span class=\"mtk1\">.</span><span class=\"mtk11\">Router</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">register</span><span class=\"mtk1\"> } = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;./auth&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/register&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk12\">register</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">module</span><span class=\"mtk1\">.</span><span class=\"mtk10\">exports</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">router</span></span></code></pre>\n<p>The last step is to import your <code>route.js</code> file as middleware in <code>server.js</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"14\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/api/auth&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;./Auth/route&quot;</span><span class=\"mtk1\">))</span></span></code></pre>\n<p>The server will use the <code>router</code> middleware function if there is a request to <code>/api/auth</code>.</p>\n<h3 id=\"test-the-register-route\" style=\"position:relative;\"><a href=\"#test-the-register-route\" aria-label=\"test the register route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test the Register Route</h3>\n<p>You'll use <a href=\"https://www.postman.com/downloads/\">Postman</a> to test all the routes.</p>\n<p>Open up Postman to send a <code>POST</code> request to <code>http://localhost:5000/api/auth/register</code> and pass the username and password to the body:</p>\n<p><img src=\"/1ac77cdb1d6c5ebf46cf5171d74cf4a0/registerRoute.webp\" alt=\"Register Route\"></p>\n<h3 id=\"login-function\" style=\"position:relative;\"><a href=\"#login-function\" aria-label=\"login function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Login Function</h3>\n<p>You've created a function that adds registered users to the database. You have to create another function that will authenticate user credentials and check if the user is registered.</p>\n<p>Open the <code>Auth.js</code> file and create the Login function, as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"15\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">// auth.js</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">login</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk3\">// Check if username and password is provided</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (!</span><span class=\"mtk12\">username</span><span class=\"mtk1\"> || !</span><span class=\"mtk12\">password</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Username or Password not present&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The <code>login</code> function returns status code <code>400</code> if the username and password were not provided. You need to find a user with the provided <code>username</code> and <code>password</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"16\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">login</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">try</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\">.</span><span class=\"mtk11\">findOne</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (!</span><span class=\"mtk12\">user</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Login not successful&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User not found&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">200</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Login successful&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">user</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;An error occurred&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Here, it returns status code <code>401</code> when a user isn't found and <code>200</code> when a user is found. The code snippet wrapped all this in a <code>tryCatch</code> block to detect and output errors, if any.</p>\n<h3 id=\"set-up-login-route\" style=\"position:relative;\"><a href=\"#set-up-login-route\" aria-label=\"set up login route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Set Up Login Route</h3>\n<p>To set up the login route, import the <code>login</code> function into your <code>route.js</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"17\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">express</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;express&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">express</span><span class=\"mtk1\">.</span><span class=\"mtk11\">Router</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">register</span><span class=\"mtk1\">, </span><span class=\"mtk12\">login</span><span class=\"mtk1\"> } = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;./auth&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk12\">login</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">module</span><span class=\"mtk1\">.</span><span class=\"mtk10\">exports</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">router</span><span class=\"mtk1\">;</span></span></code></pre>\n<h3 id=\"test-the-login-route\" style=\"position:relative;\"><a href=\"#test-the-login-route\" aria-label=\"test the login route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test the Login Route</h3>\n<p>Make a <code>POST</code> request at <code>http://localhost:5000/api/auth/login</code> and pass a valid username and password to the body:</p>\n<p><img src=\"/bdcb632806567d22933fc46296bc322c/loginroute.webp\" alt=\"login Route\"></p>\n<h3 id=\"update-function\" style=\"position:relative;\"><a href=\"#update-function\" aria-label=\"update function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Update Function</h3>\n<p>This function will be responsibile for updating the role of a basic user to an admin user. Open the <code>auth.js</code> file and create the <code>update</code> function, as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"18\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">//auth.js</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">update</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">role</span><span class=\"mtk1\">, </span><span class=\"mtk12\">id</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk3\">// Verifying if role and id is presnt</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">id</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">// Verifying if the value of role is admin</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> === </span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\">.</span><span class=\"mtk11\">findById</span><span class=\"mtk1\">(</span><span class=\"mtk12\">id</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Role is not admin&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Role or Id not present&quot;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The first <code>if</code> statement verifies if <code>role</code> and <code>id</code> are present in the request body.</p>\n<p>The second <code>if</code> statement checks if the value of <code>role</code> is admin. You should do this to avoid having over two roles.</p>\n<p>After finding a user with that ID, you'll create a third <code>if</code> block that will check for the role of the user:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"19\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">update</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">role</span><span class=\"mtk1\">, </span><span class=\"mtk12\">id</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk3\">// First - Verifying if role and id is presnt</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">id</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">// Second - Verifying if the value of role is admin</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> === </span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk3\">// Finds the user with the id</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\">.</span><span class=\"mtk11\">findById</span><span class=\"mtk1\">(</span><span class=\"mtk12\">id</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">((</span><span class=\"mtk12\">user</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk3\">// Third - Verifies the user is not an admin</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> !== </span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">role</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk11\">save</span><span class=\"mtk1\">((</span><span class=\"mtk12\">err</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk3\">//Monogodb error checker</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">res</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                  .</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;400&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                  .</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;An error occurred&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">err</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk1\"> });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">process</span><span class=\"mtk1\">.</span><span class=\"mtk11\">exit</span><span class=\"mtk1\">(</span><span class=\"mtk7\">1</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;201&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Update successful&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User is already an Admin&quot;</span><span class=\"mtk1\"> });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">catch</span><span class=\"mtk1\">((</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">res</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            .</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            .</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;An error occurred&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk1\"> });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        });</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       ...</span></span></code></pre>\n<p>The third <code>if</code> block prevents assigning an admin role to an admin user, while the last <code>if</code> block checks if an error occurred when saving the role in the database.</p>\n<blockquote>\n<p>The numerous <code>if</code> statements might be a little bit tricky but understandable. Please read the comments in the above code block for better understanding.</p>\n</blockquote>\n<h3 id=\"set-up-update-route\" style=\"position:relative;\"><a href=\"#set-up-update-route\" aria-label=\"set up update route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Set Up Update Route</h3>\n<p>Import the <code>update</code> function in your <code>route.js</code>, as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"20\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">register</span><span class=\"mtk1\">, </span><span class=\"mtk12\">login</span><span class=\"mtk1\">, </span><span class=\"mtk12\">update</span><span class=\"mtk1\"> } = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;./auth&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/update&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">put</span><span class=\"mtk1\">(</span><span class=\"mtk12\">update</span><span class=\"mtk1\">);</span></span></code></pre>\n<h3 id=\"testing-the-update-route\" style=\"position:relative;\"><a href=\"#testing-the-update-route\" aria-label=\"testing the update route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Testing the Update Route</h3>\n<p>Send a <code>put</code> request to <code>http://localhost:5000/api/auth/update</code>:</p>\n<p><img src=\"/0a64d4ef9c1c8955d9aed82aaf869472/updateroute.webp\" alt=\"update Route\"></p>\n<h3 id=\"delete-function\" style=\"position:relative;\"><a href=\"#delete-function\" aria-label=\"delete function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Delete Function</h3>\n<p>The <code>deleteUser</code> function will remove a specific user from the database. Let's create this function in our <code>auth.js</code> file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"21\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">deleteUser</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">id</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\">.</span><span class=\"mtk11\">findById</span><span class=\"mtk1\">(</span><span class=\"mtk12\">id</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">user</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk11\">remove</span><span class=\"mtk1\">())</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">user</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">201</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User successfully deleted&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">catch</span><span class=\"mtk1\">(</span><span class=\"mtk12\">error</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">res</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;An error occurred&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>You remove the user based on the <code>id</code> you get from <code>req.body</code>.</p>\n<h3 id=\"set-up-the-deleteuser-route\" style=\"position:relative;\"><a href=\"#set-up-the-deleteuser-route\" aria-label=\"set up the deleteuser route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Set up the <code>deleteUser</code> Route</h3>\n<p>Open your <code>route.js</code> file to create a <code>delete</code> request to <code>/deleteUser</code>, using the <code>deleteUser</code> as its function:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"22\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">register</span><span class=\"mtk1\">, </span><span class=\"mtk12\">login</span><span class=\"mtk1\">, </span><span class=\"mtk12\">update</span><span class=\"mtk1\">, </span><span class=\"mtk12\">deleteUser</span><span class=\"mtk1\"> } = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;./auth&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/deleteUser&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">delete</span><span class=\"mtk1\">(</span><span class=\"mtk12\">deleteUser</span><span class=\"mtk1\">);</span></span></code></pre>\n<h3 id=\"test-the-deleteuser-route\" style=\"position:relative;\"><a href=\"#test-the-deleteuser-route\" aria-label=\"test the deleteuser route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test the <code>deleteUser</code> Route</h3>\n<p>Send a <code>delete</code> request to <code>http://localhost:5000/api/auth/deleteUser</code> by passing a valid <code>id</code> to the body:</p>\n<p><img src=\"/5f7478fb8c45b5a5def8d442ab1d259c/deleteroute.webp\" alt=\"Delete Route\"></p>\n<h2 id=\"hash-user-passwords\" style=\"position:relative;\"><a href=\"#hash-user-passwords\" aria-label=\"hash user passwords permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Hash User Passwords</h2>\n<p>Saving user passwords in the database in plain text format is reckless. It is preferable to hash your password before storing it.</p>\n<p>For instance, it will be tough to decipher the passwords in your database if they are leaked. Hashing passwords is a cautious and reliable practice.</p>\n<p>Let's use <code>bcryptjs</code> to hash your user passwords.</p>\n<p>Lets install <code>bcryptjs</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"23\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">npm</span><span class=\"mtk1\"> </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bcryptjs</span></span></code></pre>\n<p>After installing <code>bcryptjs</code>, import it into your <code>auth.js</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"24\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;bcryptjs&quot;</span><span class=\"mtk1\">)</span></span></code></pre>\n<h3 id=\"refactor-register-function\" style=\"position:relative;\"><a href=\"#refactor-register-function\" aria-label=\"refactor register function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Refactor Register Function</h3>\n<p>Instead of sending a plain text format to your database, lets hash the password using <code>bcrypt</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"25\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">register</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ...</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">hash</span><span class=\"mtk1\">(</span><span class=\"mtk12\">password</span><span class=\"mtk1\">, </span><span class=\"mtk7\">10</span><span class=\"mtk1\">).</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">hash</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\">.</span><span class=\"mtk11\">create</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">username</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">hash</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">((</span><span class=\"mtk12\">user</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">200</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User successfully created&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">           </span><span class=\"mtk12\">user</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      .</span><span class=\"mtk11\">catch</span><span class=\"mtk1\">((</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User not successful created&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span></code></pre>\n<p><code>bcrypt</code> takes in your password as the first argument and the number of times it will hash the password as the second argument. Passing a large number will take <code>bcrypt</code> a long time to hash the password, so give a moderate number like 10.</p>\n<p><code>bcrypt</code> will return a promise with the hashed password; then, send that hashed password to the database.</p>\n<h3 id=\"test-the-register-function\" style=\"position:relative;\"><a href=\"#test-the-register-function\" aria-label=\"test the register function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test the Register Function</h3>\n<p>Send a <code>POST</code> request to <code>http://localhost:5000/api/auth/register</code> and pass the username and password to the body:</p>\n<p><img src=\"/1ac77cdb1d6c5ebf46cf5171d74cf4a0/Hashedregisterroute.webp\" alt=\"Register Route\"></p>\n<h3 id=\"refactor-the-login-function\" style=\"position:relative;\"><a href=\"#refactor-the-login-function\" aria-label=\"refactor the login function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Refactor the Login Function</h3>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"26\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">login</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk3\">// Check if username and password is provided</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (!</span><span class=\"mtk12\">username</span><span class=\"mtk1\"> || !</span><span class=\"mtk12\">password</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Username or Password not present&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">try</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\">.</span><span class=\"mtk11\">findOne</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">username</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (!</span><span class=\"mtk12\">user</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Login not successful&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User not found&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk3\">// comparing given password with hashed password</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">compare</span><span class=\"mtk1\">(</span><span class=\"mtk12\">password</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">password</span><span class=\"mtk1\">).</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk4\">function</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">result</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">result</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          ? </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">200</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Login successful&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">user</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          : </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Login not succesful&quot;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;An error occurred&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p><code>bcrypt.compare</code> checks if the given password and the hashed password in the database are the same.</p>\n<h3 id=\"test-the-login-function\" style=\"position:relative;\"><a href=\"#test-the-login-function\" aria-label=\"test the login function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test the Login Function</h3>\n<p>Send a <code>POST</code> request to <code>http://localhost:5000/api/auth/login</code> and pass a valid username and password to the body:</p>\n<p><img src=\"/632b08fece37d70e9641393af6d9dbcd/hashedloginroute.webp\" alt=\"Hashed Login Route\"></p>\n<h2 id=\"authenticate-users-with-json-web-token-jwt\" style=\"position:relative;\"><a href=\"#authenticate-users-with-json-web-token-jwt\" aria-label=\"authenticate users with json web token jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Authenticate Users with JSON Web Token (JWT)</h2>\n<p>JSON Web Token helps shield a route from an unauthenticated user. Using JWT in your application will prevent unauthenticated users from accessing your users' home page and prevent unauthorized users from accessing your admin page.</p>\n<p>JWT creates a token, sends it to the client, and then the client uses the token for making requests. It also helps verify that you're a valid user making those requests.</p>\n<p>You've to install JWT before using it in your application:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"27\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">npm</span><span class=\"mtk1\"> </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jsonwebtoken</span></span></code></pre>\n<h3 id=\"refactor-the-register-function\" style=\"position:relative;\"><a href=\"#refactor-the-register-function\" aria-label=\"refactor the register function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Refactor the Register Function</h3>\n<p>When a user registers, you'll send a token to the client using JWT as a cookie. To create this token, you need to set a secret string. You'll use the node's in-built package called <code>crypto</code> to create random strings:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"28\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">node</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;crypto&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">randomBytes</span><span class=\"mtk1\">(</span><span class=\"mtk7\">35</span><span class=\"mtk1\">).</span><span class=\"mtk11\">toString</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;hex&quot;</span><span class=\"mtk1\">)</span></span></code></pre>\n<p>Output:</p>\n<p><img src=\"/ffc516c1cf1c578ae020aab9ea7bef3d/crypto.webp\" alt=\"Crypto\"></p>\n<p>Storing this secret string in an environment variable is a safe practice. If this secret string is leaked, unauthenticated users can create fake tokens to access the route.</p>\n<p>Store your secret string in a variable:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"29\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jwtSecret</span><span class=\"mtk1\"> =</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk8\">&quot;4715aed3c946f7b0a38e6b534a9583628d84e96d10fbc04700770d572af3dce43625dd&quot;</span></span></code></pre>\n<p>Once you've created your <code>jwtSecret</code>, import <code>jsonwebtoken</code> as the token in the <code>register</code> function:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"30\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;jsonwebtoken&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jwtSecret</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&#39;4715aed3c946f7b0a38e6b534a9583628d84e96d10fbc04700770d572af3dce43625dd&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">register</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ...</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">hash</span><span class=\"mtk1\">(</span><span class=\"mtk12\">password</span><span class=\"mtk1\">, </span><span class=\"mtk7\">10</span><span class=\"mtk1\">).</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">hash</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\">.</span><span class=\"mtk11\">create</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">username</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">hash</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">((</span><span class=\"mtk12\">user</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">maxAge</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">3</span><span class=\"mtk1\"> * </span><span class=\"mtk7\">60</span><span class=\"mtk1\"> * </span><span class=\"mtk7\">60</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">token</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">sign</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          { </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">_id</span><span class=\"mtk1\">, </span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">role:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">jwtSecret</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">expiresIn:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">maxAge</span><span class=\"mtk1\">, </span><span class=\"mtk3\">// 3hrs in sec</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">cookie</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;jwt&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">token</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">httpOnly:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">maxAge:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">maxAge</span><span class=\"mtk1\"> * </span><span class=\"mtk7\">1000</span><span class=\"mtk1\">, </span><span class=\"mtk3\">// 3hrs in ms</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">201</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User successfully created&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">user:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">_id</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      .</span><span class=\"mtk11\">catch</span><span class=\"mtk1\">((</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User not successful created&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span></code></pre>\n<p>The code snippet created the token using JWT's <code>sign</code> function. This function takes in three parameters:</p>\n<ul>\n<li>the payload is the first parament that you'll pass to the function. This payload holds data concerning the user, and this data should not contain sensitive information like passwords;</li>\n<li>you passed your <code>jwtSecret</code> as the second parameter; and,</li>\n<li>how long the token will last as the third parameter.</li>\n</ul>\n<p>After passing all these arguments, JWT will generate a token. After the token is generated, send it as a cookie to the client.</p>\n<h3 id=\"refactor-the-login-function-1\" style=\"position:relative;\"><a href=\"#refactor-the-login-function-1\" aria-label=\"refactor the login function 1 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Refactor the Login Function</h3>\n<p>Also, generate a token for logged in users:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"31\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">login</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ...</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">compare</span><span class=\"mtk1\">(</span><span class=\"mtk12\">password</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">password</span><span class=\"mtk1\">).</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk4\">function</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">result</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">result</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">maxAge</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">3</span><span class=\"mtk1\"> * </span><span class=\"mtk7\">60</span><span class=\"mtk1\"> * </span><span class=\"mtk7\">60</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">token</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">sign</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            { </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">_id</span><span class=\"mtk1\">, </span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">role:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">jwtSecret</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">expiresIn:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">maxAge</span><span class=\"mtk1\">, </span><span class=\"mtk3\">// 3hrs in sec</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">cookie</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;jwt&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">token</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">httpOnly:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">maxAge:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">maxAge</span><span class=\"mtk1\"> * </span><span class=\"mtk7\">1000</span><span class=\"mtk1\">, </span><span class=\"mtk3\">// 3hrs in ms</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">201</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User successfully Logged in&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">user:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">_id</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Login not succesful&quot;</span><span class=\"mtk1\"> });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;An error occurred&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span></code></pre>\n<h3 id=\"protect-the-routes\" style=\"position:relative;\"><a href=\"#protect-the-routes\" aria-label=\"protect the routes permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Protect the Routes</h3>\n<p>To prevent unauthenticated users from accessing the private route, take the token from the cookie, verify the token, and redirect users based on role.</p>\n<p>You'll get the token from the client using a node package called <code>cookie-parser</code>. Let's install the package before using it:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"32\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">npm</span><span class=\"mtk1\"> </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> </span><span class=\"mtk12\">cookie</span><span class=\"mtk1\">-</span><span class=\"mtk12\">parser</span></span></code></pre>\n<p>After installing it, import it into your <code>server.js</code> file and use it as a <em>middleware</em>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"33\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">cookieParser</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;cookie-parser&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk11\">cookieParser</span><span class=\"mtk1\">());</span></span></code></pre>\n<p>You'll create your middleware that verifies the token and grants access to your private route.</p>\n<p>Let's create a new folder in the project's folder named <code>middleware</code> and create a file called <code>auth.js</code>.</p>\n<h3 id=\"admin-authentication\" style=\"position:relative;\"><a href=\"#admin-authentication\" aria-label=\"admin authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Admin Authentication</h3>\n<p>Open the <code>auth.js</code> file and create the middleware:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"34\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;jsonwebtoken&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jwtSecret</span><span class=\"mtk1\"> =</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk8\">&quot;4715aed3c946f7b0a38e6b534a9583628d84e96d10fbc04700770d572af3dce43625dd&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">adminAuth</span><span class=\"mtk1\"> = (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">token</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">cookies</span><span class=\"mtk1\">.</span><span class=\"mtk12\">jwt</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">token</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">verify</span><span class=\"mtk1\">(</span><span class=\"mtk12\">token</span><span class=\"mtk1\">, </span><span class=\"mtk12\">jwtSecret</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">, </span><span class=\"mtk12\">decodedToken</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Not authorized&quot;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">decodedToken</span><span class=\"mtk1\">.</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> !== </span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Not authorized&quot;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk11\">next</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      .</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      .</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Not authorized, token not available&quot;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The code snippet requests a token from the client, checks if a token is available, and verifies that token.</p>\n<p>JWT verifies your token with your <code>jwtSecret</code> and returns a callback function. This function returns status code <code>401</code> if the token fails the authentication test.</p>\n<p>When you've created the token, you passed a payload that contained the user's credentials. You'll get the role from the credentials and check if the user's role is admin. If the user is not an admin, you return status code <code>401</code>, but you'll call the <code>next</code> function if the user is an admin.</p>\n<h3 id=\"basic-user-authentication\" style=\"position:relative;\"><a href=\"#basic-user-authentication\" aria-label=\"basic user authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Basic User Authentication</h3>\n<p>You'll also authenticate basic users before granting them access to the users route. Let's create another middleware in your <code>auth.js</code> file that will authenticate basic users:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"35\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">userAuth</span><span class=\"mtk1\"> = (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">token</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">cookies</span><span class=\"mtk1\">.</span><span class=\"mtk12\">jwt</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">token</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">verify</span><span class=\"mtk1\">(</span><span class=\"mtk12\">token</span><span class=\"mtk1\">, </span><span class=\"mtk12\">jwtSecret</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">, </span><span class=\"mtk12\">decodedToken</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Not authorized&quot;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">decodedToken</span><span class=\"mtk1\">.</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> !== </span><span class=\"mtk8\">&quot;Basic&quot;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Not authorized&quot;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk11\">next</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      .</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      .</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Not authorized, token not available&quot;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<h3 id=\"protect-the-routes-1\" style=\"position:relative;\"><a href=\"#protect-the-routes-1\" aria-label=\"protect the routes 1 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Protect the Routes</h3>\n<p>You'll have two routes: one for the user and the other for the admin. Let's import this middleware into your <code>server.js</code> file and protect your routes:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"36\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">adminAuth</span><span class=\"mtk1\">, </span><span class=\"mtk12\">userAuth</span><span class=\"mtk1\"> } = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;./middleware/auth.js&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/admin&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">adminAuth</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">send</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Admin Route&quot;</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/basic&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">userAuth</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">send</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;User Route&quot;</span><span class=\"mtk1\">));</span></span></code></pre>\n<p>Updating user roles and deleting users should be done by an Admin, so you need to import this <code>auth.js</code> middleware into your <code>route.js</code> file to protect the <code>update</code> and <code>delete</code> routes.</p>\n<p><code>route.js</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"37\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">adminAuth</span><span class=\"mtk1\"> } = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;../middleware/auth&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/update&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">put</span><span class=\"mtk1\">(</span><span class=\"mtk12\">adminAuth</span><span class=\"mtk1\">, </span><span class=\"mtk12\">update</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/deleteUser&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">delete</span><span class=\"mtk1\">(</span><span class=\"mtk12\">adminAuth</span><span class=\"mtk1\">, </span><span class=\"mtk12\">deleteUser</span><span class=\"mtk1\">)</span></span></code></pre>\n<h2 id=\"populate-the-database-with-admin-user\" style=\"position:relative;\"><a href=\"#populate-the-database-with-admin-user\" aria-label=\"populate the database with admin user permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Populate the Database with Admin User</h2>\n<p>You need to create an admin user in your database. Open up your terminal, and let's run some <a href=\"https://docs.mongodb.com/manual/reference/method/\">MongoDB methods</a>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"38\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">mongo</span></code></pre>\n<p>After mongo is started, you need to use the <code>role_auth</code> database:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"39\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">use role_auth</span></code></pre>\n<p>Before adding your admin user to the database, you need to hash the password using <code>bcrypt</code> in the <code>node</code> terminal. Open node terminal in your project's directory:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"40\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;bcryptjs&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">hash</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk7\">10</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">password</span></span></code></pre>\n<p>After you've created the constant <code>password</code>, you need to enter <code>the</code> <code>password</code> in the node terminal to get your hashed password.</p>\n<p><img src=\"/d3c1b2d70849b827aac61c69995a2f8f/nodebycrypt.webp\" alt=\"Node bcrypt\"></p>\n<p>You'll use the hashed password to create your admin:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"41\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">db</span><span class=\"mtk1\">.</span><span class=\"mtk12\">users</span><span class=\"mtk1\">.</span><span class=\"mtk11\">insert</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;$2a$10$mZwU9AbYSyX7E1A6fu/ZO.BDhmCOIK7k6jXvKcuJm93PyYuH2eZ3K&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">role:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span></code></pre>\n<p>To check if it was successfully created, run <code>db.users.find().pretty()</code> — this will output all users in the database.</p>\n<h2 id=\"create-the-login-form-using-ejs\" style=\"position:relative;\"><a href=\"#create-the-login-form-using-ejs\" aria-label=\"create the login form using ejs permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create the Login Form Using EJS</h2>\n<p>You'll use Embedded JavaScript (EJS) to create a front-end for your application.</p>\n<p>Install the <code>ejs</code> package:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"42\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">npm</span><span class=\"mtk1\"> </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> </span><span class=\"mtk12\">ejs</span></span></code></pre>\n<p>After you've installed <code>ejs</code>, you need to set <code>ejs</code> as your default <em>view engine</em> in your <code>server.js</code> file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"43\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">set</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;view engine&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;ejs&quot;</span><span class=\"mtk1\">)</span></span></code></pre>\n<h3 id=\"render-embedded-javascript\" style=\"position:relative;\"><a href=\"#render-embedded-javascript\" aria-label=\"render embedded javascript permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Render Embedded JavaScript</h3>\n<p>When making a <code>GET</code> request to specific routes, you'll render an <code>ejs</code> file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"44\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/&quot;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">render</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;home&quot;</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/register&quot;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">render</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;register&quot;</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">render</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;login&quot;</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/admin&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">adminAuth</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">render</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/basic&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">userAuth</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">render</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;user&quot;</span><span class=\"mtk1\">))</span></span></code></pre>\n<h3 id=\"create-ejs-files\" style=\"position:relative;\"><a href=\"#create-ejs-files\" aria-label=\"create ejs files permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create EJS Files</h3>\n<p>By default, your application will look into the <code>views</code> folder when rendering an <code>ejs</code> file. You need to create the <code>views</code> folder in your project's folder and add your <code>ejs</code> files to it</p>\n<h3 id=\"create-a-home-page\" style=\"position:relative;\"><a href=\"#create-a-home-page\" aria-label=\"create a home page permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create a Home Page</h3>\n<p>Your home page will contain the links to <code>/login</code> and <code>/register</code> ejs file. Open up <code>home.ejs</code> and add these links:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"45\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!</span><span class=\"mtk12\">DOCTYPE</span><span class=\"mtk1\"> </span><span class=\"mtk12\">html</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">html</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lang</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;en&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">charset</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;UTF-8&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;viewport&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;width=device-width, initial-scale=1.0&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Home page</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Home Page</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/register&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> Register</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">a</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Login</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">a</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h3 id=\"create-a-registration-form\" style=\"position:relative;\"><a href=\"#create-a-registration-form\" aria-label=\"create a registration form permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create a Registration Form</h3>\n<p>Embedded JavaScript (EJS) supports HTML syntax. You'll create the registration form in <code>register.ejs</code> using HTML syntax:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"46\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!</span><span class=\"mtk12\">DOCTYPE</span><span class=\"mtk1\"> </span><span class=\"mtk12\">html</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">html</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lang</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;en&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">charset</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;UTF-8&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;viewport&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;width=device-width, initial-scale=1.0&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Register Page</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Register Page</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">form</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">style</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;background-color: red;&quot;</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">label</span><span class=\"mtk1\"> </span><span class=\"mtk12\">for</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;username&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Username</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">label</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;text&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;username&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">required</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">label</span><span class=\"mtk1\"> </span><span class=\"mtk12\">for</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Password</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">label</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">required</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;submit&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;register&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">form</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Already registered? Login</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">a</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h3 id=\"add-post-request-functionality\" style=\"position:relative;\"><a href=\"#add-post-request-functionality\" aria-label=\"add post request functionality permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Add POST Request Functionality</h3>\n<p>You need to get the username and password that the user entered and pass it to the body when making the <code>POST</code> request:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"47\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  const form = document.querySelector(&#39;form&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  const username = document.querySelector(&#39;#username&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  const password = document.querySelector(&#39;#password&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  const display = document.querySelector(&#39;.error&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  form.addEventListener(&#39;submit&#39;, async (e) =&gt; </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk12\">e</span><span class=\"mtk1\">.</span><span class=\"mtk11\">preventDefault</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk12\">display</span><span class=\"mtk1\">.</span><span class=\"mtk12\">textContent</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&#39;&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk12\">try</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       const </span><span class=\"mtk12\">res</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/api/auth/register&#39;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span><span class=\"mtk12\">method:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;POST&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">body:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">username</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">password</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\"> }),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> { </span><span class=\"mtk8\">&#39;Content-Type&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk1\"> }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       const </span><span class=\"mtk12\">data</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span><span class=\"mtk11\">if</span><span class=\"mtk1\">(res.status === 400 || res.status === 401){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">display</span><span class=\"mtk1\">.</span><span class=\"mtk12\">textContent</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">`</span><span class=\"mtk4\">${</span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk4\">}</span><span class=\"mtk8\">. </span><span class=\"mtk4\">${</span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk1\"> ? </span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk1\"> : </span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       data.</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> === </span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\"> ? </span><span class=\"mtk12\">location</span><span class=\"mtk1\">.</span><span class=\"mtk11\">assign</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/admin&#39;</span><span class=\"mtk1\">) : </span><span class=\"mtk12\">location</span><span class=\"mtk1\">.</span><span class=\"mtk11\">assign</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/basic&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        } </span><span class=\"mtk11\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          console.log(err.message)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">}</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">&lt;/</span><span class=\"mtk12\">body</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">&lt;/</span><span class=\"mtk12\">html</span><span class=\"mtk1\">&gt;</span></span></code></pre>\n<p>The code snippet uses JavaScript's in-built library called <code>fetch</code> to send a POST request to <code>/api/auth/register</code>.</p>\n<p>After the request has been sent, it stores the response to a constant <code>res</code>.</p>\n<p><code>res.json</code> will return the JSON you've passed as a response in the API.</p>\n<p>When <code>res.json</code> returns the data, you store that data in a constant <code>data</code>.</p>\n<p>If you get an error while making the request, display the error to the user. If an error isn't found, redirect the user based on their role on different routes.</p>\n<h3 id=\"create-a-login-form\" style=\"position:relative;\"><a href=\"#create-a-login-form\" aria-label=\"create a login form permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create a Login Form</h3>\n<p>Creating your login form and adding functionality to it will be similar to that of your registration. Open <code>login.ejs</code> and create this form:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"48\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!</span><span class=\"mtk12\">DOCTYPE</span><span class=\"mtk1\"> </span><span class=\"mtk12\">html</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">html</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lang</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;en&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">charset</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;UTF-8&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;viewport&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;width=device-width, initial-scale=1.0&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Login Page</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Login Page</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">form</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">style</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;background-color: red;&quot;</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">label</span><span class=\"mtk1\"> </span><span class=\"mtk12\">for</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;username&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Username</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">label</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;text&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;username&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">required</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">label</span><span class=\"mtk1\"> </span><span class=\"mtk12\">for</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Password</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">label</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">required</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;submit&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;login&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">form</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/register&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Don&#39;t have an accout? Register</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">a</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h3 id=\"add-post-request-functionality-1\" style=\"position:relative;\"><a href=\"#add-post-request-functionality-1\" aria-label=\"add post request functionality 1 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Add POST Request Functionality</h3>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"49\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const form = document.querySelector(&#39;form&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const username = document.querySelector(&#39;#username&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const password = document.querySelector(&#39;#password&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const display = document.querySelector(&#39;.error&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      form.addEventListener(&#39;submit&#39;, async (e) =&gt; </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">e</span><span class=\"mtk1\">.</span><span class=\"mtk11\">preventDefault</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">display</span><span class=\"mtk1\">.</span><span class=\"mtk12\">textContent</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&#39;&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">try</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          const </span><span class=\"mtk12\">res</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/api/auth/login&#39;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">method:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;POST&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">body:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">username</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">password</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\"> }),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> { </span><span class=\"mtk8\">&#39;Content-Type&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk1\"> }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          const </span><span class=\"mtk12\">data</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk11\">if</span><span class=\"mtk1\"> (res.status === 400 || res.status === 401) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">display</span><span class=\"mtk1\">.</span><span class=\"mtk12\">textContent</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">`</span><span class=\"mtk4\">${</span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk4\">}</span><span class=\"mtk8\">. </span><span class=\"mtk4\">${</span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk1\"> ? </span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk1\"> : </span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          data.</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> === </span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\"> ? </span><span class=\"mtk12\">location</span><span class=\"mtk1\">.</span><span class=\"mtk11\">assign</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/admin&#39;</span><span class=\"mtk1\">) : </span><span class=\"mtk12\">location</span><span class=\"mtk1\">.</span><span class=\"mtk11\">assign</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/basic&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        } </span><span class=\"mtk11\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            console.log(err.message)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">}</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    &lt;/</span><span class=\"mtk12\">body</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    &lt;/</span><span class=\"mtk12\">html</span><span class=\"mtk1\">&gt;</span></span></code></pre>\n<h2 id=\"add-registered-users-to-the-route\" style=\"position:relative;\"><a href=\"#add-registered-users-to-the-route\" aria-label=\"add registered users to the route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Add Registered Users to the Route</h2>\n<p>Once you've redirected users based on role to different routes, display all registered users on that route. You need to send a <code>GET</code> request to <code>/getUsers</code>.</p>\n<p>Open <code>auth.js</code> file in <code>Auth</code> folder:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"50\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getUsers</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\">.</span><span class=\"mtk11\">find</span><span class=\"mtk1\">({})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">users</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">userFunction</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">users</span><span class=\"mtk1\">.</span><span class=\"mtk11\">map</span><span class=\"mtk1\">(</span><span class=\"mtk12\">user</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">container</span><span class=\"mtk1\"> = {}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">container</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">container</span><span class=\"mtk1\">.</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">role</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">container</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">200</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">user:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">userFunction</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">catch</span><span class=\"mtk1\">(</span><span class=\"mtk12\">err</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Not successful&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">err</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The <code>User.find</code> method returns an array of users. After mapping through this array, it stores the username and role in the constant <code>container</code> and returns the <code>container</code>.</p>\n<h3 id=\"display-registered-user-in-user-route\" style=\"position:relative;\"><a href=\"#display-registered-user-in-user-route\" aria-label=\"display registered user in user route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Display Registered User in <code>user</code> Route</h3>\n<p>You've rendered <code>user.ejs</code> when accessing the <code>/user</code> route. Now, you'll display all registered users to that route.</p>\n<p><code>user.ejs</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"51\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!</span><span class=\"mtk12\">DOCTYPE</span><span class=\"mtk1\"> </span><span class=\"mtk12\">html</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">html</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lang</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;en&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">charset</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;UTF-8&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">http-equiv</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;X-UA-Compatible&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;IE=edge&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;viewport&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;width=device-width, initial-scale=1.0&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">User page</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Users</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">ul</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">ul</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const ul = document.querySelector(&quot;ul&quot;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const getUsers = async () =&gt; </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/api/auth/getUsers&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">data</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk11\">map</span><span class=\"mtk1\">(</span><span class=\"mtk12\">mappedUser</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">mappedUser</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</span><span class=\"mtk1\"> !== </span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">li</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">`&lt;li&gt; &lt;b&gt;Username&lt;/b&gt; =&gt; </span><span class=\"mtk4\">${</span><span class=\"mtk12\">mappedUser</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</span><span class=\"mtk4\">}</span><span class=\"mtk8\"> &lt;br&gt; &lt;b&gt;Role&lt;/b&gt; =&gt; </span><span class=\"mtk4\">${</span><span class=\"mtk12\">mappedUser</span><span class=\"mtk1\">.</span><span class=\"mtk12\">role</span><span class=\"mtk4\">}</span><span class=\"mtk8\"> &lt;/li&gt;`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">ul</span><span class=\"mtk1\">.</span><span class=\"mtk12\">innerHTML</span><span class=\"mtk1\"> += </span><span class=\"mtk12\">li</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">null</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      getUsers()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h3 id=\"add-update-and-delete-function-to-the-admin-route\" style=\"position:relative;\"><a href=\"#add-update-and-delete-function-to-the-admin-route\" aria-label=\"add update and delete function to the admin route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Add Update and Delete Function to the Admin Route</h3>\n<p>You'll also display registered users to the admin route but add <code>update</code> and <code>delete</code> functionality to the route:</p>\n<p><code>admin.ejs</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"52\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!</span><span class=\"mtk12\">DOCTYPE</span><span class=\"mtk1\"> </span><span class=\"mtk12\">html</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">html</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lang</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;en&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">charset</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;UTF-8&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">http-equiv</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;X-UA-Compatible&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;IE=edge&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;viewport&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;width=device-width, initial-scale=1.0&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Admin page</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;display&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">style</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;background-color: red;&quot;</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Users</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">ul</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">ul</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const ul = document.querySelector(&quot;ul&quot;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const display = document.querySelector(&quot;.display&quot;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const getUsers = async () =&gt; </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/api/auth/getUsers&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">data</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk11\">map</span><span class=\"mtk1\">(</span><span class=\"mtk12\">mappedUser</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">mappedUser</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</span><span class=\"mtk1\"> !== </span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">li</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">`&lt;li&gt; &lt;b&gt;Username&lt;/b&gt; =&gt; </span><span class=\"mtk4\">${</span><span class=\"mtk12\">mappedUser</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</span><span class=\"mtk4\">}</span><span class=\"mtk8\"> &lt;br&gt; &lt;b&gt;Role&lt;/b&gt; =&gt; </span><span class=\"mtk4\">${</span><span class=\"mtk12\">mappedUser</span><span class=\"mtk1\">.</span><span class=\"mtk12\">role</span><span class=\"mtk4\">}</span><span class=\"mtk8\"> &lt;/li&gt; &lt;button class=&quot;edit&quot;&gt;Edit Role&lt;/button&gt; &lt;button class=&quot;delete&quot;&gt;Delete User&lt;/button&gt;`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">ul</span><span class=\"mtk1\">.</span><span class=\"mtk12\">innerHTML</span><span class=\"mtk1\"> += </span><span class=\"mtk12\">li</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">null</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">editRole</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">querySelectorAll</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;.edit&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">deleteUser</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">querySelector</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;.delete&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      getUsers()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h3 id=\"edit-a-users-role\" style=\"position:relative;\"><a href=\"#edit-a-users-role\" aria-label=\"edit a users role permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Edit a User's Role</h3>\n<p>You'll create an event listener that will listen for a click on the <code>Edit Role</code> button. When the button is clicked, you'll send a <code>PUT</code> request to <code>/api/auth/update</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"53\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ...</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    const editRole = document.querySelectorAll(&#39;.edit&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    const deleteUser = document.querySelector(&#39;.delete&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  editRole.forEach((button, i) =&gt; </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">button</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addEventListener</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;click&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk4\">async</span><span class=\"mtk1\">() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">display</span><span class=\"mtk1\">.</span><span class=\"mtk12\">textContent</span><span class=\"mtk1\">= </span><span class=\"mtk8\">&#39;&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">user</span><span class=\"mtk1\">[</span><span class=\"mtk12\">i</span><span class=\"mtk1\">+</span><span class=\"mtk7\">1</span><span class=\"mtk1\">].</span><span class=\"mtk12\">id</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/api/auth/update&#39;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">method:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;PUT&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">body:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">role:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;admin&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">id</span><span class=\"mtk1\">}),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> { </span><span class=\"mtk8\">&#39;Content-Type&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk1\"> }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">dataUpdate</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> === </span><span class=\"mtk7\">400</span><span class=\"mtk1\"> || </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> === </span><span class=\"mtk7\">401</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\">.</span><span class=\"mtk12\">scrollTop</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">0</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk12\">documentElement</span><span class=\"mtk1\">.</span><span class=\"mtk12\">scrollTop</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">0</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">display</span><span class=\"mtk1\">.</span><span class=\"mtk12\">textContent</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">`</span><span class=\"mtk4\">${</span><span class=\"mtk12\">dataUpdate</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk4\">}</span><span class=\"mtk8\">. </span><span class=\"mtk4\">${</span><span class=\"mtk12\">dataUpdate</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk1\"> ? </span><span class=\"mtk12\">dataUpdate</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk1\"> : </span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">location</span><span class=\"mtk1\">.</span><span class=\"mtk11\">assign</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/admin&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">}</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h3 id=\"delete-users\" style=\"position:relative;\"><a href=\"#delete-users\" aria-label=\"delete users permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Delete Users</h3>\n<p>Deleting Users from the database should be the duty of an admin.</p>\n<p><code>admin.ejs</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"54\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ...</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  const editRole = document.querySelectorAll(&#39;.edit&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  const deleteUser = document.querySelector(&#39;.delete&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  deleteUser.forEach((button, i)=&gt; </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk12\">button</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addEventListener</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;click&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> ()</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk12\">display</span><span class=\"mtk1\">.</span><span class=\"mtk12\">textContent</span><span class=\"mtk1\"> =</span><span class=\"mtk8\">&#39;&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">user</span><span class=\"mtk1\">[</span><span class=\"mtk12\">i</span><span class=\"mtk1\">+</span><span class=\"mtk7\">1</span><span class=\"mtk1\">].</span><span class=\"mtk12\">id</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/api/auth/deleteUser&#39;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk12\">method:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;DELETE&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk12\">body:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">({</span><span class=\"mtk12\">id</span><span class=\"mtk1\">}),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> {</span><span class=\"mtk8\">&#39;Content-Type&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">dataDelete</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> === </span><span class=\"mtk7\">401</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\">.</span><span class=\"mtk12\">scrollTop</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">0</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk12\">documentElement</span><span class=\"mtk1\">.</span><span class=\"mtk12\">scrollTop</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">0</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">display</span><span class=\"mtk1\">.</span><span class=\"mtk12\">textContent</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">`</span><span class=\"mtk4\">${</span><span class=\"mtk12\">dataUpdate</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk4\">}</span><span class=\"mtk8\">. </span><span class=\"mtk4\">${</span><span class=\"mtk12\">dataUpdate</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk1\"> ? </span><span class=\"mtk12\">dataUpdate</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk1\"> : </span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk12\">location</span><span class=\"mtk1\">.</span><span class=\"mtk11\">assign</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/admin&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">}</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>You've created an event listener that listens for a click on the <code>Delete User</code> button. When the button is clicked, you'll send a <code>DELETE</code> request to <code>/api/auth/deleteUser</code>.</p>\n<blockquote>\n<p>Please ensure the admin user is first on the list to avoid populating the database with an admin user again.</p>\n</blockquote>\n<h2 id=\"logout-functionality\" style=\"position:relative;\"><a href=\"#logout-functionality\" aria-label=\"logout functionality permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Logout Functionality</h2>\n<p>To log out users, you need to remove the token from the client and redirect the client to the home page.</p>\n<p>You'll create a <code>GET</code> request to <code>/logout</code> in the <code>server.js</code> file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"55\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/logout&quot;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">cookie</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;jwt&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">, { </span><span class=\"mtk12\">maxAge:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;1&quot;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">redirect</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span></code></pre>\n<p>The code snippet replaced the JWT token with an empty string and gave it a lifespan of 1 second.</p>\n<p>After creating the <code>GET</code> request, add a logout button to the admin's route and user's route:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"56\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">ul</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">ul</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;logout&quot;</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/logout&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Log Out</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">a</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span></code></pre>\n<h2 id=\"nodejs-authentication-with-loginradius\" style=\"position:relative;\"><a href=\"#nodejs-authentication-with-loginradius\" aria-label=\"nodejs authentication with loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Node.js Authentication with LoginRadius</h2>\n<p>You can simply replace the many steps discussed above using <a href=\"https://www.loginradius.com/docs/api/v2/getting-started/introduction/\">LoginRadius</a>. In turn, it helps you focus more on developing core application features while letting you quickly implement user signup and login and manager users.</p>\n<p>In other words, LoginRadius is a SaaS-based customer identity and access management (CIAM) system with features to manage customer identity, privacy, and access. It is a simple, implementable solution for adding user authentication and authorization to your website.</p>\n<p>Basically, LoginRadius handles user registration, login, and authentication. Other features of LoginRadius include:</p>\n<ul>\n<li><strong>Forms</strong>: LoginRadius can automatically pre-create registration and login forms for you.</li>\n<li><strong>Authentication and Authorization</strong>: It generates and sends a token to the user when login or signup is successful. Instead of using <code>JWT</code>, you can use this token to authenticate users</li>\n<li><strong>Security</strong>: When using LoginRadius, you automatically have access to an admin console where you can control authentication factors, such as email, phone, and multi-factor auth for your Node.js app.</li>\n</ul>\n<p>To get started with LoginRadius, you need to <a href=\"https://accounts.loginradius.com/auth.aspx\">create an account</a> with either the free plan or the Developer plan, customize your registration and login forms, and start managing your users.</p>\n<h3 id=\"how-to-authenticate-your-nodejs-app-with-loginradius\" style=\"position:relative;\"><a href=\"#how-to-authenticate-your-nodejs-app-with-loginradius\" aria-label=\"how to authenticate your nodejs app with loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to Authenticate Your Node.js App with LoginRadius</h3>\n<p>This section briefly covers how authentication works with LoginRadius.</p>\n<p>After signing up for LoginRadius, choose a name for your Node.js app.</p>\n<blockquote>\n<p><img src=\"/faed37adab3b93cbf078cb49970ff8a6/loginradius.webp\" alt=\"LoginRadius - Enter your app name\"></p>\n</blockquote>\n<p>After completing your LoginRadius signup process, you can get your <strong>App Name</strong>, <strong>API Key</strong>, and <strong>API Secret</strong> from the <code>configuration</code> link on the sidebar. With these configurations, you can easily link the server-side of our application to LoginRadius.</p>\n<p><img src=\"/3c5de91ef87963f5ea96eb10556ba358/loginradius1.webp\" alt=\"LoginRadius API Credentials\"></p>\n<p>LoginRadius automatically generates a link that will be used to authenticate users. This link contains the name of your LoginRadius application and a <code>URL</code> that authenticated users will be redirected to:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"57\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">https://&lt;LoginRadius-APP-Name&gt;.hub.loginradius.com/auth.aspx?action=login&return_url=&lt;Return-URL&gt;</span></code></pre>\n<p>An instance of the link is given below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"58\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">https://noderoleauth.hub.loginradius.com/auth.aspx?action=login&return_url=http://localhost:5000</span></code></pre>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>You've successfully learned how to perform CRUD operations using MongoDB as a database, hash passwords, authenticate using JWT, and render Embedded JavaScript (EJS). You can put all these together to build more complex applications.</p>\n<h2 id=\"resources\" style=\"position:relative;\"><a href=\"#resources\" aria-label=\"resources permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Resources</h2>\n<ul>\n<li>A full, working version of <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/NodeJs/NodejsAuthenticationGuide\">the code used in this tutorial is available on GitHub</a></li>\n<li><a href=\"https://www.loginradius.com/developers/\">Node.js Authentication with LoginRadius</a></li>\n</ul>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk17 { color: #808080; }\n</style>","frontmatter":{"date":"January 18, 2022","updated_date":null,"description":"Want to authenticate and manage users with specific roles in your Node.js app? This in-depth tutorial explains everything step-by-step to help you implement authentication in your Node.js apps.","title":"Node.js User Authentication Guide","tags":["JWT","Authentication","Node.js"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.9047619047619047,"src":"/static/36e3e372636f4119a2bf4ee3878592ae/58556/coverimage.webp","srcSet":"/static/36e3e372636f4119a2bf4ee3878592ae/61e93/coverimage.webp 200w,\n/static/36e3e372636f4119a2bf4ee3878592ae/1f5c5/coverimage.webp 400w,\n/static/36e3e372636f4119a2bf4ee3878592ae/58556/coverimage.webp 800w,\n/static/36e3e372636f4119a2bf4ee3878592ae/bfd1f/coverimage.webp 1034w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Uma Victor","github":"uma-victor1","avatar":null}}}},{"node":{"excerpt":"In this article, you'll learn about authentication in Next.js and how you can authenticate Next.js applications with LoginRadius. Note: An…","fields":{"slug":"/engineering/guest-post/nextjs-authentication-guide/"},"html":"<p>In this article, you'll learn about authentication in Next.js and how you can authenticate Next.js applications with <a href=\"https://www.loginradius.com/\">LoginRadius</a>.</p>\n<blockquote>\n<p><strong>Note:</strong> An understanding of <a href=\"https://reactjs.org/\">React</a>, <a href=\"https://www.loginradius.com/blog/engineering/react-hooks-guide/\">Hooks</a>, and <a href=\"https://nextjs.org/\">Next.js</a> is beneficial to follow this tutorial.</p>\n</blockquote>\n<h2 id=\"what-is-authentication\" style=\"position:relative;\"><a href=\"#what-is-authentication\" aria-label=\"what is authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is Authentication?</h2>\n<p>Authentication is the process of validating that an individual is who they claim to be. Authentication is an essential feature for applications, particularly those that store user data.</p>\n<p>You should not mistake authentication for authorization. Authorization is the process of verifying that whether a user has required permission to access an asset or data set.</p>\n<p>Authentication deals with identifying a user, while authorization checks what resources or data an authenticated user has permission to access.</p>\n<p>Some of the methods used to implement authentication are:</p>\n<ul>\n<li>Username/email and password</li>\n<li>Fingerprint</li>\n<li>Face recognition</li>\n<li>Security questions</li>\n<li>One time pins (OTPs)</li>\n<li>Magic links</li>\n</ul>\n<h2 id=\"should-you-build-your-authentication-system-or-use-a-third-party-solution\" style=\"position:relative;\"><a href=\"#should-you-build-your-authentication-system-or-use-a-third-party-solution\" aria-label=\"should you build your authentication system or use a third party solution permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Should You Build Your Authentication System or Use a Third-party Solution?</h2>\n<p>Authentication is one of the most critical parts of an application’s security, so you should address it adequately.</p>\n<p>A few aspects you should consider when assessing if you should build your authentication system or use a third-party solution:</p>\n<ul>\n<li><strong>Progressive Enhancements:</strong> Security systems require frequent enhancements and upgrades to keep users safe from evolving threats and techniques. How much time and resources can you commit to keeping your security system up-to-date with the latest countermeasures to safeguard data and access against emerging threats?</li>\n<li>\n<p><strong>Identity Provider Support:</strong> How many identity providers do you plan to support, if any? With third-party solutions, you can authenticate users with email/password as well as identity providers such as Google, Github, Facebook, and more. Third-party solutions are always working hard to add support to even more providers. They also provide other authentication methods like Magic Link for passwordless authentication.</p>\n<p>Can you build an authentication system that allows users to use their preferred authentication method, or will they be restricted?</p>\n</li>\n<li>\n<p><strong>Advanced Security Features:</strong> Security and authentication go beyond email/password sign-in. Most third-party solutions provide necessary features, such as email confirmation, two-factor authentication (2FA), etc.</p>\n<p>You should let the security experts such as LoginRadius do what they do best while focusing on your main tasks — building excellent applications.</p>\n</li>\n</ul>\n<p>Considering these factors, it's pretty easier to rely on a third-party solution, and it's also cheaper and more secure than building your own authentication system.</p>\n<h2 id=\"what-is-loginradius\" style=\"position:relative;\"><a href=\"#what-is-loginradius\" aria-label=\"what is loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is LoginRadius?</h2>\n<blockquote>\n<p>Loginradius is the world's first no-code identity platform. It is a simple, implementable solution for adding user authentication and authorization to your website.</p>\n</blockquote>\n<p>LoginRadius provides no-code services for authorization, authentication, account security, and much more. It has several interesting features, and some of them are:</p>\n<ul>\n<li><a href=\"https://www.loginradius.com/social-login/\">Social login</a></li>\n<li><a href=\"https://www.loginradius.com/passwordless-login/\">Passwordless login</a></li>\n<li><a href=\"https://www.loginradius.com/standard-login/\">Standard login (email and password)</a></li>\n<li><a href=\"https://www.loginradius.com/multi-factor-authentication/\">Multi-factor authentication</a></li>\n<li><a href=\"https://www.loginradius.com/phone-login/\">Phone login</a></li>\n<li><a href=\"https://www.loginradius.com/single-sign-on/\">Single sign-on</a></li>\n<li><a href=\"https://www.loginradius.com/profile-management/\">User management</a></li>\n</ul>\n<h2 id=\"understanding-nextjs-authentication-patterns\" style=\"position:relative;\"><a href=\"#understanding-nextjs-authentication-patterns\" aria-label=\"understanding nextjs authentication patterns permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Understanding Next.js Authentication Patterns</h2>\n<p>Next.js offers two authentication patterns — client-side and server-side authentication.</p>\n<h3 id=\"client-side-authentication\" style=\"position:relative;\"><a href=\"#client-side-authentication\" aria-label=\"client side authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Client-Side Authentication</h3>\n<p>With client-side authentication, the authentication logic and user redirection are done in the browser. The page component fully loads before the redirect logic is executed.</p>\n<p>When this authentication approach is used, developers usually use a loading indicator to indicate to the user that a process is running in the background. The loading indicator helps boost user experience. If the user’s authentication fails, redirect the user to a login page.</p>\n<p>The following example shows how to handle client-side redirects:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">useEffect</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;react&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">useRouter</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;next/router&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">authService</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;auth-service&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk3\">//imaginary auth service</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">ProtectedPage</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">useRouter</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">useEffect</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">authUser</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">authService</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getUser</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">// if there is no authenticated user, redirect to login page_</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (!</span><span class=\"mtk12\">authUser</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">push</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }, [])</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Welcome </span><span class=\"mtk4\">{</span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span><span class=\"mtk4\">}</span><span class=\"mtk1\">. This is a protected page</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The above code snippet handles client-side redirects in the browser using <a href=\"https://nextjs.org/docs/api-reference/next/router\">next/router</a>. It also uses an imaginary authentication service, <code>auth-service</code>, for illustration purposes. You’ll work with LoginRadius later in this tutorial.</p>\n<p>It checks if there is an authenticated user with the <code>authService.getUser()</code> method in the <code>useEffect</code>. If there is none, it redirects the user to the <code>/login</code> page using Next.js’s router object.</p>\n<p>This is a simple illustration of client-side authentication and redirection.</p>\n<h3 id=\"server-side-authentication\" style=\"position:relative;\"><a href=\"#server-side-authentication\" aria-label=\"server side authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Server-Side Authentication</h3>\n<p>With server-side authentication, you can redirect a user from, say, <code>pages/profile</code> to <code>pages/login</code>. When non-authenticated users try to access a protected page, they are redirected to a login page. All of this is done on the server — before the request reaches the browser.</p>\n<p>A benefit of this pattern is that non-authenticated users do not see flashes of unauthenticated content before they are redirected.</p>\n<p>The following example below shows how to handle server-side redirects:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">ProtectedPage</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> }) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk17\">&lt;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t</span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Welcome </span><span class=\"mtk4\">{</span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span><span class=\"mtk4\">}</span><span class=\"mtk1\">. This is a protected page</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk17\">&lt;/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">getServerSideProps</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk12\">context</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">authService</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getUser</span><span class=\"mtk1\">(</span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">req</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk3\">// if there is no authenticated user, redirect to login page</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (!</span><span class=\"mtk12\">user</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk15\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t</span><span class=\"mtk12\">props:</span><span class=\"mtk1\"> {},</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t</span><span class=\"mtk12\">redirect:</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">destination:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk15\">return</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">props:</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> } }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Using <code>getServerSideProps</code> enables rendering pages on the server. You can take advantage of that to also handle the redirection on the server.</p>\n<p>The above code snippet uses the <code>authService.getUser()</code> method to get the authenticated user’s object. If there is no user, it returns an object with a <code>redirect</code> object. The <code>redirect</code> object contains a <code>destination</code> key, where you can put the page you want to redirect the user to, which is your application’s login page.</p>\n<p>Now that you’ve understood the authentication patterns available, let’s see how to authenticate a Next.js application with LoginRadius.</p>\n<h2 id=\"authenticating-nextjs-apps-with-loginradius\" style=\"position:relative;\"><a href=\"#authenticating-nextjs-apps-with-loginradius\" aria-label=\"authenticating nextjs apps with loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Authenticating Next.js Apps with LoginRadius</h2>\n<p>The steps below highlight how you can integrate and authenticate your Next.js applications with LoginRadius:</p>\n<h3 id=\"create-a-loginradius-account\" style=\"position:relative;\"><a href=\"#create-a-loginradius-account\" aria-label=\"create a loginradius account permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create a LoginRadius Account</h3>\n<p>You should <a href=\"https://accounts.loginradius.com/auth.aspx?return_url=https://dashboard.loginradius.com/login&#x26;action=register\">create an account</a> to get started with LoginRadius. There is a free plan you can start with.</p>\n<h3 id=\"get-account-credentials\" style=\"position:relative;\"><a href=\"#get-account-credentials\" aria-label=\"get account credentials permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Get Account Credentials</h3>\n<p>Now that you have an account, you should <a href=\"https://www.loginradius.com/developers/\">get the credentials</a> for your <code>appName</code> and <code>apiKey</code> from the dashboard. You'll need them later to use the React SDK.</p>\n<h3 id=\"start-a-new-nextjs-application\" style=\"position:relative;\"><a href=\"#start-a-new-nextjs-application\" aria-label=\"start a new nextjs application permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Start a New Next.js Application</h3>\n<p>Run the following command in your terminal to create a new Next.js application:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">npx</span><span class=\"mtk1\"> </span><span class=\"mtk12\">create</span><span class=\"mtk1\">-</span><span class=\"mtk12\">next</span><span class=\"mtk1\">-</span><span class=\"mtk12\">app</span><span class=\"mtk1\"> &lt;</span><span class=\"mtk12\">name</span><span class=\"mtk1\">-</span><span class=\"mtk4\">of</span><span class=\"mtk1\">-</span><span class=\"mtk12\">project</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//or</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">yarn</span><span class=\"mtk1\"> </span><span class=\"mtk12\">add</span><span class=\"mtk1\"> </span><span class=\"mtk12\">create</span><span class=\"mtk1\">-</span><span class=\"mtk12\">next</span><span class=\"mtk1\">-</span><span class=\"mtk12\">app</span><span class=\"mtk1\"> &lt;</span><span class=\"mtk12\">name</span><span class=\"mtk1\">-</span><span class=\"mtk4\">of</span><span class=\"mtk1\">-</span><span class=\"mtk12\">project</span><span class=\"mtk1\">&gt;</span></span></code></pre>\n<h3 id=\"install-loginradius-react-sdk\" style=\"position:relative;\"><a href=\"#install-loginradius-react-sdk\" aria-label=\"install loginradius react sdk permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Install LoginRadius React SDK</h3>\n<p>Next, install the <a href=\"https://github.com/LoginRadius/loginradius-react\">React SDK</a> into the project:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">```javascript</span>\n<span class=\"grvsc-line\">npm install loginradius-react</span>\n<span class=\"grvsc-line\">//or</span>\n<span class=\"grvsc-line\">yarn add loginradius-react</span>\n<span class=\"grvsc-line\">```</span></code></pre>\n<h3 id=\"integrate-the-react-sdk\" style=\"position:relative;\"><a href=\"#integrate-the-react-sdk\" aria-label=\"integrate the react sdk permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Integrate the React SDK</h3>\n<p>You need to wrap the root component with the SDK’s authentication provider.</p>\n<p>You also need to pass the account credentials to the provider. You can get these credentials from your LoginRadius account dashboard.</p>\n<p>Navigate to <code>pages/_app.js</code> and update it with the code below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Head</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;next/head&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">LRAuthProvider</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;loginradius-react&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">ChakraProvider</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@chakra-ui/react&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Layout</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../layout&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../styles/globals.css&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">MyApp</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">Component</span><span class=\"mtk1\">, </span><span class=\"mtk12\">pageProps</span><span class=\"mtk1\"> }) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Loginradius Next</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">LRAuthProvider</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">appName</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;your-app-name&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">apiKey</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;your-api-key&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">redirectUri</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk8\">&quot;http://localhost:3000/&quot;</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">ChakraProvider</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Layout</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Component</span><span class=\"mtk1\"> </span><span class=\"mtk4\">{</span><span class=\"mtk1\">...</span><span class=\"mtk12\">pageProps</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Layout</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">ChakraProvider</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">LRAuthProvider</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">MyApp</span></span></code></pre>\n<p>The above code snippet imports the <code>LRAuthProvider</code> component from <code>loginradius-react</code>. It passes the <code>appName</code> and <code>apiKey</code> taken from the LoginRadius account dashboard earlier to <code>LRAuthProvider</code>. It also sets the <code>redirectUri</code> to <code>http://localhost:3000/</code>.</p>\n<p>The <code>redirectUri</code> is the callback URL where you want to redirect users after being authenticated. You should <a href=\"https://www.loginradius.com/developers/\">whitelist the <code>redirect_uri</code> in your LoginRadius account dashboard</a>. Localhost URLs are whitelisted by default.</p>\n<p>Now that you've integrated the SDK, let’s add the authentication functionality.</p>\n<h3 id=\"add-login-and-logout-functionality\" style=\"position:relative;\"><a href=\"#add-login-and-logout-functionality\" aria-label=\"add login and logout functionality permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Add Login and Logout Functionality</h3>\n<p>Your users should be able to log in and out of our application, so let’s set that up.</p>\n<p>We will add the log in and log out functionality to a <code>Nav</code> component. Let’s set up the component.</p>\n<p>Create a <code>layout</code> folder in the root directory, and create a <code>Nav.js</code> file there. Add the following code to <code>Nav.js</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Button</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Flex</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Stack</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@chakra-ui/react&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">useLRAuth</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;loginradius-react&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Nav</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">loginWithRedirect</span><span class=\"mtk1\">, </span><span class=\"mtk12\">logout</span><span class=\"mtk1\"> } = </span><span class=\"mtk11\">useLRAuth</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Flex</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Stack</span><span class=\"mtk1\"> </span><span class=\"mtk12\">spacing</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">[</span><span class=\"mtk7\">6</span><span class=\"mtk1\">, </span><span class=\"mtk7\">8</span><span class=\"mtk1\">]</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">onClick</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk11\">loginWithRedirect</span><span class=\"mtk1\">()</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Login to continue</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">onClick</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk11\">logout</span><span class=\"mtk1\">()</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Log out</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Stack</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Flex</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Here, <a href=\"https://chakra-ui.com/\">Chakra UI</a> is used for UI components.</p>\n<p>First, it imports the <code>useLRAuth</code> hook from the SDK. Next, it accesses the <code>loginWithRedirect</code> and <code>logout</code> methods from the <code>useLRAuth</code> hook.</p>\n<p>Then, it passes <code>loginWithRedirect</code> and <code>logout</code> to the login and logout buttons’ <code>onClick</code> event handlers, respectively.</p>\n<p>Having created the <code>Nav</code> component, we need to create the <code>Layout</code> component we mentioned earlier.</p>\n<p>Create an <code>index.js</code> file in the <code>layout</code> folder, and paste the code below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Box</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@chakra-ui/react&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Nav</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./Nav&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Layout</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">children</span><span class=\"mtk1\"> }) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Box</span><span class=\"mtk1\"> </span><span class=\"mtk12\">h</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;100vh&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bg</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;green.50&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Nav</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Box</span><span class=\"mtk17\">&gt;</span><span class=\"mtk4\">{</span><span class=\"mtk12\">children</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Box</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Box</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>With that, you've added authentication to your application. However, you need a way to track the authentication state. You need to know if there is a logged-in user and do something with that information.</p>\n<h3 id=\"tracking-authentication-state\" style=\"position:relative;\"><a href=\"#tracking-authentication-state\" aria-label=\"tracking authentication state permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Tracking Authentication State</h3>\n<p>The SDK also provides <code>error</code> and <code>user</code> objects, along with <code>isLoading</code> and <code>isAuthenticated</code> booleans. You'll use these to track the authentication state.</p>\n<p>You can access information about an authenticated user, such as their email address, from the <code>user</code> object. If any, you can display error messages from the <code>error</code> object.</p>\n<p><code>isAuthenticated</code> returns true if there is an authenticated user and false if there is not.</p>\n<p>We are currently rendering both the login and logout buttons in the <code>Nav</code> component. However, we don’t want that. We want to display the login button when there is no authenticated user and logout when there is an authenticated user.</p>\n<p>Let’s update the <code>Nav.js</code> file with the code below to fix that:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Button</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Flex</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Stack</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@chakra-ui/react&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">useLRAuth</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;loginradius-react&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Nav</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">isAuthenticated</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user</span><span class=\"mtk1\">, </span><span class=\"mtk12\">loginWithRedirect</span><span class=\"mtk1\">, </span><span class=\"mtk12\">logout</span><span class=\"mtk1\"> } = </span><span class=\"mtk11\">useLRAuth</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Flex</span><span class=\"mtk1\"> </span><span class=\"mtk12\">as</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;nav&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Stack</span><span class=\"mtk1\"> </span><span class=\"mtk12\">spacing</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">[</span><span class=\"mtk7\">6</span><span class=\"mtk1\">, </span><span class=\"mtk7\">8</span><span class=\"mtk1\">]</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">{</span><span class=\"mtk1\">!</span><span class=\"mtk12\">user</span><span class=\"mtk1\"> && (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">onClick</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk11\">loginWithRedirect</span><span class=\"mtk1\">()</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Login to continue</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        )</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">{</span><span class=\"mtk12\">isAuthenticated</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> && (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">onClick</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk11\">logout</span><span class=\"mtk1\">()</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Log out</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        )</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Stack</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Flex</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>We conditionally display the login and logout buttons based on the authentication state.</p>\n<p>If there is a logged-in user, we want to redirect them to the profile page.</p>\n<p>Navigate to <code>pages/index.js</code> file and update it with the code below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">useEffect</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;react&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">useRouter</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;next/router&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">useLRAuth</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;loginradius-react&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Button</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Heading</span><span class=\"mtk1\">, </span><span class=\"mtk12\">VStack</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Center</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@chakra-ui/react&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Home</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">isLoading</span><span class=\"mtk1\">, </span><span class=\"mtk12\">isAuthenticated</span><span class=\"mtk1\">, </span><span class=\"mtk12\">error</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> } = </span><span class=\"mtk11\">useLRAuth</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">useRouter</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">useEffect</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">user</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">isAuthenticated</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">push</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/profile&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }, [</span><span class=\"mtk12\">router</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user</span><span class=\"mtk1\">, </span><span class=\"mtk12\">isAuthenticated</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">isLoading</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Loading...</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Oops... </span><span class=\"mtk4\">{</span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Center</span><span class=\"mtk1\"> </span><span class=\"mtk12\">pt</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk7\">10</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">VStack</span><span class=\"mtk1\"> </span><span class=\"mtk12\">spacing</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">[</span><span class=\"mtk7\">6</span><span class=\"mtk1\">, </span><span class=\"mtk7\">8</span><span class=\"mtk1\">]</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Heading</span><span class=\"mtk1\"> </span><span class=\"mtk12\">as</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;h2&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Welcome</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Heading</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Text</span><span class=\"mtk1\"> </span><span class=\"mtk12\">fontSize</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;3xl&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Login to continue</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Text</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">VStack</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Center</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Let’s break down the above code snippet:</p>\n<ul>\n<li>In the <code>useEffect</code>, it checks if there is a user object and if <code>isAuthenticated</code> is true. If these conditions are true, it redirects the user to their profile page. These conditions will only be true when the user has logged in. You'll set up the profile page later.</li>\n<li>It checks if the page is loading using the <code>isLoading</code> boolean. If true, it displays “loading…”. In a production-ready application, you would display a loading spinner.</li>\n<li>If there is an error during the authentication process, it accesses the message from the <code>error</code> object and displays it to the user.</li>\n<li>Finally, return some JSX.</li>\n</ul>\n<h3 id=\"displaying-authenticated-user-data\" style=\"position:relative;\"><a href=\"#displaying-authenticated-user-data\" aria-label=\"displaying authenticated user data permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Displaying Authenticated User Data</h3>\n<p>You have to display information about the authenticated user. Let’s set that up.\nCreate a profile.js file in the pages directory and paste the code below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Box</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Center</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Heading</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@chakra-ui/react&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">useLRAuth</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;loginradius-react&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Profile</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">user</span><span class=\"mtk1\">, </span><span class=\"mtk12\">isLoading</span><span class=\"mtk1\">, </span><span class=\"mtk12\">isAuthenticated</span><span class=\"mtk1\"> } = </span><span class=\"mtk11\">useLRAuth</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">isLoading</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Loading...</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">isAuthenticated</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Box</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Center</span><span class=\"mtk1\"> </span><span class=\"mtk12\">mt</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk7\">10</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Heading</span><span class=\"mtk1\"> </span><span class=\"mtk12\">a</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;h2&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            Welcome to your profile </span><span class=\"mtk4\">{</span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Email</span><span class=\"mtk1\">[</span><span class=\"mtk7\">0</span><span class=\"mtk1\">].</span><span class=\"mtk12\">Value</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Heading</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Center</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Box</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>You should display a user’s information if they're authenticated. Here, you check that they're authenticated with the <code>isAuthenticated</code> hook. If they're authenticated, return some JSX and display the user’s email address.</p>\n<h3 id=\"protecting-a-route\" style=\"position:relative;\"><a href=\"#protecting-a-route\" aria-label=\"protecting a route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Protecting a Route</h3>\n<p>You can create protected routes to ensure only authenticated users can access those routes.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">withAuthenticationRequired</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;loginradius-react&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Profile</span><span class=\"mtk1\"> = () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">isAuthenticated</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t</span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Box</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t\t</span><span class=\"mtk14\">...markup</span><span class=\"mtk1\"> </span><span class=\"mtk12\">goes</span><span class=\"mtk1\"> </span><span class=\"mtk12\">here</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t</span><span class=\"mtk14\">&lt;/Box</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk14\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk14\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk14\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">export</span><span class=\"mtk1\"> </span><span class=\"mtk12\">default</span><span class=\"mtk1\"> </span><span class=\"mtk14\">withAuthenticationRequired(Profile,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk3\">//Show a message while the user waits to be redirected to the login page.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk14\">onRedirecting:</span><span class=\"mtk1\"> </span><span class=\"mtk14\">()</span><span class=\"mtk1\"> </span><span class=\"mtk14\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk14\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk14\">&lt;div&gt;Redirecting</span><span class=\"mtk1\"> </span><span class=\"mtk12\">you</span><span class=\"mtk1\"> </span><span class=\"mtk12\">to</span><span class=\"mtk1\"> </span><span class=\"mtk12\">LoginRadius</span><span class=\"mtk1\"> </span><span class=\"mtk12\">awesome</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Login</span><span class=\"mtk1\"> </span><span class=\"mtk14\">page&lt;/div&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk14\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk14\">});</span></span></code></pre>\n<p>Here, the code snippet uses the <code>withAuthenticationRequired</code> higher-order component to wrap the <code>Profile</code> component. With this, anytime an unauthenticated user tries to access the <code>/profile</code> route, they'll be redirected to LoginRadius’s login page and then back to <code>/profile</code> after they log in.</p>\n<p>The image below shows an authenticated user's profile page.</p>\n<p><img src=\"/628d48eec1fa72e582fdd05f76b085e4/profile-page.webp\" alt=\"An authenticated user&#x27;s profile page\"></p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>In this tutorial, you have learned about user authentication and understood whether you should develop an authentication system in-house or use a modern identity platform like LoginRadius.</p>\n<p>Then, you have briefly learned different authentication patterns available in Next.js. And you step-by-step understood how to authenticate Next.js applications with LoginRadius’s React SDK.</p>\n<p>A working version of the code used in this tutorial <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/Nextjs/next-auth-demo\">is available on Github</a>.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk17 { color: #808080; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk14 { color: #F44747; }\n</style>","frontmatter":{"date":"January 13, 2022","updated_date":null,"description":"This tutorial describes Next.js authentication patterns and helps you learn step-by-step how to authenticate a Next.js application.","title":"Your Ultimate Guide to Next.js Authentication","tags":["Authentication","React","Next.js","LoginRadius"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7699115044247788,"src":"/static/6a3f9e6ed0b8803f9523875b01d55a37/58556/next-authentication.webp","srcSet":"/static/6a3f9e6ed0b8803f9523875b01d55a37/61e93/next-authentication.webp 200w,\n/static/6a3f9e6ed0b8803f9523875b01d55a37/1f5c5/next-authentication.webp 400w,\n/static/6a3f9e6ed0b8803f9523875b01d55a37/58556/next-authentication.webp 800w,\n/static/6a3f9e6ed0b8803f9523875b01d55a37/99238/next-authentication.webp 1200w,\n/static/6a3f9e6ed0b8803f9523875b01d55a37/7c22d/next-authentication.webp 1600w,\n/static/6a3f9e6ed0b8803f9523875b01d55a37/25f09/next-authentication.webp 1920w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Emadamerho-Atori Nefe","github":"nefejames","avatar":null}}}}]},"markdownRemark":{"excerpt":"Introduction Ever wondered how apps like Spotify, Netflix, or Slack manage seamless login experiences across devices? Many of them use JWT…","fields":{"slug":"/engineering/how-to-integrate-jwt/"},"html":"<h2 id=\"introduction\" style=\"position:relative;\"><a href=\"#introduction\" aria-label=\"introduction permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Introduction</h2>\n<p>Ever wondered how apps like Spotify, Netflix, or Slack manage seamless login experiences across devices? Many of them use JWT, or JSON Web Tokens, a compact, stateless method for securely transmitting user identity and session data across services.</p>\n<p>With JWT token authentication, identity information is embedded in a signed token, allowing you to maintain user sessions without server-side storage. This approach is highly scalable and ideal for modern architectures like SPAs, mobile apps, and microservices.</p>\n<p>In this blog, we’ll walk you through what is JWT, why use it, and how to implement JWT authentication using LoginRadius. </p>\n<p>You’ll learn what JWT is, why it’s effective, and how it works in real-world applications. We'll cover both integration methods (IDX and Direct API), generating your signing key, managing sessions, storing the JWT token securely, and applying best practices throughout.</p>\n<p>Whether you're a developer, product manager, or IAM architect, this guide offers a complete foundation for implementing JWT token authentication into your application stack.</p>\n<h2 id=\"what-is-jwt\" style=\"position:relative;\"><a href=\"#what-is-jwt\" aria-label=\"what is jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is JWT?</h2>\n<p><a href=\"https://www.loginradius.com/blog/engineering/jwt/\">JSON Web Token (JWT)</a> is an open standard (RFC 7519) used to transmit information securely between parties as a JSON object. It’s compact, self-contained, and digitally signed, making it a reliable format for authentication and authorization across modern applications.</p>\n<p>A JWT consists of three parts:</p>\n<ol>\n<li><strong>Header –</strong> Contains metadata like the type of token and signing algorithm (e.g., HS256).</li>\n<li><strong>Payload –</strong> Stores the actual data or “claims,” such as user ID, roles, and token expiry.</li>\n<li><strong>Signature –</strong> A cryptographic hash that ensures the token hasn’t been tampered with.</li>\n</ol>\n<p><em>Example of a token structure:</em></p>\n<p>&#x3C;base64Header>.&#x3C;base64Payload>.&#x3C;signature></p>\n<h2 id=\"why-use-jwt\" style=\"position:relative;\"><a href=\"#why-use-jwt\" aria-label=\"why use jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Why Use JWT?</h2>\n<ul>\n<li><strong>Stateless Authentication</strong>: No server-side session storage is needed — the token holds all necessary user info. </li>\n<li><strong>Portable</strong>: Works seamlessly across domains, services, and APIs. </li>\n<li><strong>Scalable</strong>: Ideal for microservices, SPAs, mobile apps, and serverless functions. </li>\n<li><strong>Interoperable</strong>: JWTs are supported across many languages and frameworks.</li>\n</ul>\n<h2 id=\"how-jwt-works\" style=\"position:relative;\"><a href=\"#how-jwt-works\" aria-label=\"how jwt works permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How JWT Works?</h2>\n<p><img src=\"/f29edbf2978577390c7ffa02e9bc4dda/lr-JWT-authentication.webp\" alt=\"Flowchart illustrating LoginRadius JWT authentication via Identity Provider (IDP), showing user redirection from login icon to login page, authentication with IDP, JWT token validation, and subsequent redirection to the customer&#x27;s website or error page based on validation results.\"></p>\n<ol>\n<li>A user logs in with credentials. </li>\n<li>Your app (or identity provider like LoginRadius) issues a signed JWT. </li>\n<li>The client stores the token and sends it with each request (usually in the Authorization header). </li>\n<li>The server validates the token’s signature and claims. </li>\n<li>If valid, access is granted — without any session stored on the backend.</li>\n</ol>\n<p>JWT simplifies identity verification, especially when you're building apps that talk to APIs or need to scale without centralized session storage.</p>\n<h2 id=\"jwt-authentication-with-loginradius-overview\" style=\"position:relative;\"><a href=\"#jwt-authentication-with-loginradius-overview\" aria-label=\"jwt authentication with loginradius overview permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>JWT Authentication with LoginRadius: Overview</h2>\n<p>LoginRadius provides robust support for JWT (JSON Web Token) authentication, which allows for flexible and secure access control across different digital platforms. Whether you're building a fully custom identity flow or using a pre-built interface, the platform supports various integration approaches depending on your architecture.</p>\n<p>If you're looking to understand how to implement JWT token authentication effectively, LoginRadius offers two primary implementation models that cater to different levels of customization and control:</p>\n<h3 id=\"1-idx-implementation--jwt-through-a-hosted-login-page\" style=\"position:relative;\"><a href=\"#1-idx-implementation--jwt-through-a-hosted-login-page\" aria-label=\"1 idx implementation  jwt through a hosted login page permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. IDX Implementation – JWT through a Hosted Login Page</h3>\n<p>The IDX-hosted login approach enables secure, standards-compliant, JWT-based authentication without requiring you to build a custom login interface. This is a strategic option for fast, compliant, and user-friendly deployments.</p>\n<ul>\n<li>The Identity Experience Framework (IDX) comes with a fully custom branded hosted login page.</li>\n<li>Once the user logs in and gets enrolled, the user’s JWTs are automatically generated and issued. These tokens can be utilized for managing user sessions and accessing the APIs.</li>\n<li>This approach simplifies deployment without compromising on user experience and security standards.</li>\n</ul>\n<h3 id=\"configuration-steps\" style=\"position:relative;\"><a href=\"#configuration-steps\" aria-label=\"configuration steps permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>Configuration Steps:</strong></h3>\n<ol>\n<li>Enable JWT Login</li>\n<li>Go to <a href=\"https://console.loginradius.com/authentication/authentication-configuration\">authentication configuration settings</a> and enable JWT Login in the Admin Console.</li>\n</ol>\n<p><img src=\"/9fb19dd9c88c7916aeebd03ab6e661b7/lr-admin-console.webp\" alt=\"Screenshot of LoginRadius Admin Console showing JWT Custom IDP configuration interface with options for provider name, algorithm (HS256), key entry, clock skew, and expiration time settings.\"></p>\n<ol start=\"2\">\n<li>Specify your signing algorithm and expiry policy, and define your JWT Secret Key.</li>\n<li>Input a secure JWT signing key.</li>\n<li>Specify token expiry duration (e.g., 15–60 minutes)</li>\n<li>Select the desired algorithm —HS256 for symmetric signing (same key signs and verifies)</li>\n<li>RS256 for asymmetric signing, where LoginRadius securely stores the private key used to sign the JWT.</li>\n<li>Your app or backend service uses the public key to validate the token signature.</li>\n<li>LoginRadius provides a JWKS (JSON Web Key Set) endpoint to dynamically fetch and rotate public keys, ensuring trust without key exposure.</li>\n<li>Update IDX Template for Callback</li>\n<li>Modify your IDX login page template to retrieve the JWT post-login. You can access the token via redirect URL parameters or secure JavaScript callbacks.</li>\n</ol>\n<h3 id=\"example-response\" style=\"position:relative;\"><a href=\"#example-response\" aria-label=\"example response permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example Response:</h3>\n<p>{</p>\n<p>  \"access_token\": \"eyJhbGciOiJIUzI1NiIsInR...\",</p>\n<p>  \"expires_in\": 1800</p>\n<p>}</p>\n<p>This integration approach works best for all teams that want effective identity workflows without the complexity of building proprietary login screens, something that is crucial for customer portals, onboarding of mobile applications, and even managing access for business partners.</p>\n<h3 id=\"2-direct-api-implementation--self-managed-login\" style=\"position:relative;\"><a href=\"#2-direct-api-implementation--self-managed-login\" aria-label=\"2 direct api implementation  self managed login permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. Direct API Implementation – Self Managed Login</h3>\n<p>If you’re building a custom login UI or working in a headless environment, LoginRadius lets you generate and handle JWTs directly through its <a href=\"https://www.loginradius.com/docs/api/v2/customer-identity-api/\">Authentication APIs</a>. Here’s how you can programmatically perform token authentication using the classic method:</p>\n<ul>\n<li>For custom front-end applications, LR offers an API to authenticate users and issue JWT tokens.</li>\n<li>In response to the login request, the developers are provided with signed tokens that can be validated on the client’s side or by downstream services.</li>\n<li>This method is best fit for enterprise applications that have complex custom workflows or are designed to be embedded into other applications.</li>\n</ul>\n<h3 id=\"configuration-steps-1\" style=\"position:relative;\"><a href=\"#configuration-steps-1\" aria-label=\"configuration steps 1 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>Configuration Steps:</strong></h3>\n<h4 id=\"step-1-authenticate-via-api\" style=\"position:relative;\"><a href=\"#step-1-authenticate-via-api\" aria-label=\"step 1 authenticate via api permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 1: Authenticate via API:</h4>\n<ul>\n<li>\n<p>Send a POST login request to the LR Authentication URL: </p>\n<p>POST /identity/v2/auth/login</p>\n</li>\n</ul>\n<p>Include the user’s credentials (email + password) in the request body.</p>\n<h4 id=\"step-2-get-jwt-in-response\" style=\"position:relative;\"><a href=\"#step-2-get-jwt-in-response\" aria-label=\"step 2 get jwt in response permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 2: Get JWT in Response</h4>\n<ul>\n<li>If the user credentials are authentic, then the JWT token will be available in response.</li>\n</ul>\n<p>{</p>\n<p> \"access_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",</p>\n<p> \"expires_in\": 3600</p>\n<p>}</p>\n<h4 id=\"step-3-jwt-decoding-and-validation\" style=\"position:relative;\"><a href=\"#step-3-jwt-decoding-and-validation\" aria-label=\"step 3 jwt decoding and validation permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 3: JWT Decoding and Validation</h4>\n<ul>\n<li>Use any JWT library (e.g., jsonwebtoken for Node.js or pyjwt for Python) to decode the token.</li>\n<li>Validate the signature using your configured secret key.</li>\n<li>Confirm claims like exp, iat, aud, and iss.</li>\n</ul>\n<h4 id=\"step-4-set-custom-claims-optional\" style=\"position:relative;\"><a href=\"#step-4-set-custom-claims-optional\" aria-label=\"step 4 set custom claims optional permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 4: Set Custom Claims (Optional)</h4>\n<p>With LoginRadius, it is possible to customize the payload to include user roles and/or any additional metadata. You can set custom JWT claims on the Admin Console.</p>\n<p>With this method, you have complete customization over login flows while using LoginRadius to issue signed JWTs for user session management.</p>\n<p><strong>NOTE-</strong> With either method, LoginRadius ensures that JWTs are securely signed, optionally short-lived, and compatible with standard token validation libraries, making integration seamless for everyone.</p>\n<p>To get started with JWT implementation, you can<a href=\"https://www.loginradius.com/docs/single-sign-on/federated-sso/jwt-login/jwt-implementation-guide/\"> read our complete developer documentation</a>. </p>\n<h2 id=\"hosted-login-vs-direct-api\" style=\"position:relative;\"><a href=\"#hosted-login-vs-direct-api\" aria-label=\"hosted login vs direct api permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Hosted Login vs Direct API</h2>\n<p><img src=\"/15ec02ac98d24a9f1f28e5d0f06b9174/IDX-vs-Direct-API-JWT.webp\" alt=\"Illustration showing IDX vs Direct API JWT flow diagram comparing LoginRadius JWT authentication methods via Hosted Login Page (IDX) and Custom Login UI using Direct API, illustrating user login, JWT issuance, and token return process.\"></p>\n<h2 id=\"what-is-session-management-and-how-it-works-with-jwt\" style=\"position:relative;\"><a href=\"#what-is-session-management-and-how-it-works-with-jwt\" aria-label=\"what is session management and how it works with jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is Session Management and How It Works with JWT</h2>\n<p><a href=\"https://www.loginradius.com/blog/identity/user-session-management/\">Session management </a>is how your app keeps track of a user after they log in so they don’t have to prove who they are with every request.</p>\n<p>In traditional apps, sessions are stored on the server using session IDs. Every time a request comes in, the server checks that session ID to verify the user.</p>\n<p>In modern apps, especially SPAs and APIs, JWTs are used to manage sessions without needing server-side storage; this is called stateless session management. The token itself carries the user’s identity, roles, and expiration details. As long as the token is valid, the user stays logged in.</p>\n<p>Good session management ensures:</p>\n<ul>\n<li>Security against session hijacking</li>\n<li>Fast user validation without hitting a database</li>\n<li>Smooth experiences with token refresh strategies</li>\n</ul>\n<h2 id=\"how-loginradius-handles-session-management-with-jwt\" style=\"position:relative;\"><a href=\"#how-loginradius-handles-session-management-with-jwt\" aria-label=\"how loginradius handles session management with jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How LoginRadius Handles Session Management with JWT:</h2>\n<ol>\n<li>\n<p>User Logs In </p>\n<ul>\n<li>LoginRadius returns an access token (JWT) and, optionally, a refresh token.</li>\n</ul>\n</li>\n<li>\n<p>Client Stores the Token </p>\n<ul>\n<li>Access tokens are stored in memory, sessionStorage, or secure cookies. </li>\n<li>They’re sent on every request via the Authorization: Bearer header. </li>\n</ul>\n</li>\n<li>\n<p>Access Token Expiry </p>\n<ul>\n<li>These tokens are short-lived by design (e.g., 15–30 minutes). </li>\n<li>Once expired, the client can use the refresh token to request a new access token. </li>\n</ul>\n</li>\n<li>\n<p>Token Renewal </p>\n<ul>\n<li>LoginRadius validates the refresh token and issues a new JWT, i.e., no user re-authentication is needed. </li>\n<li>Refresh tokens can be revoked at any time.</li>\n</ul>\n</li>\n<li>Logout and Token Revocation Strategy</li>\n</ol>\n<p>When the user logs out, both the access token and refresh token should be cleared from client storage.</p>\n<ul>\n<li>The refresh token can be explicitly revoked via the LoginRadius API, terminating the ability to renew sessions. </li>\n<li>\n<p>However, access tokens are stateless and cannot be revoked mid-lifecycle unless: </p>\n<ul>\n<li>You maintain a blacklist of token IDs (jti claims) and check them on each request. </li>\n<li>You use short-lived access tokens to limit exposure naturally. </li>\n<li>Or, you rotate your JWT signing key, invalidating all previously issued tokens. </li>\n</ul>\n</li>\n</ul>\n<p>Combining these strategies gives you greater control over token misuse and enables a robust, enterprise-grade logout flow. </p>\n<p><a href=\"https://www.loginradius.com/resource/whitepaper/secure-api-using-oauth2\"><img src=\"/e55ae4bbc8ce62e13f03e46e29ebe7cc/api-economy.webp\" alt=\"illustration showing LoginRadius free downloadable resource named API economy is transforming digitization: how to secure it using oauth 2.0.\"></a></p>\n<h2 id=\"how-to-store-jwt-tokens\" style=\"position:relative;\"><a href=\"#how-to-store-jwt-tokens\" aria-label=\"how to store jwt tokens permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to Store JWT Tokens?</h2>\n<p>When you implement JWT-based authentication, the client (browser or mobile app) needs a way to store the access token and, optionally, the refresh token after they are issued by the authentication server. This stored token is then attached to every subsequent request to prove the user's identity.</p>\n<p>Choosing where to store the JWT is a crucial security decision. The most common storage options are:</p>\n<ul>\n<li>localStorage</li>\n<li>sessionStorage</li>\n<li>HTTP-only cookies</li>\n</ul>\n<p>Each option has trade-offs between security, accessibility, and persistence, and the right choice depends on your application's architecture and threat model.</p>\n<h4 id=\"recommended-storage-strategy\" style=\"position:relative;\"><a href=\"#recommended-storage-strategy\" aria-label=\"recommended storage strategy permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Recommended Storage Strategy</h4>\n<ul>\n<li>\n<p>Access Tokens </p>\n<ul>\n<li>For SPAs: store in memory or sessionStorage for short-term access </li>\n<li>If stored in the browser, protect against XSS </li>\n</ul>\n</li>\n<li>\n<p>Refresh Tokens</p>\n<ul>\n<li>Always store the JWT refresh token in HTTP-only secure cookies to prevent JavaScript access. This adds a critical layer of protection against XSS attacks.</li>\n<li>Combine with SameSite=Strict or SameSite=Lax attributes to mitigate CSRF risks and ensure the JWT refresh token is only sent in intended contexts.</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"best-practices-for-storing-jwts\" style=\"position:relative;\"><a href=\"#best-practices-for-storing-jwts\" aria-label=\"best practices for storing jwts permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Best Practices for Storing JWTs</h2>\n<ol>\n<li>Never store sensitive tokens (like refresh tokens) in localStorage or sessionStorage.</li>\n<li>Use Secure and HttpOnly flags with cookies to prevent JavaScript access and ensure transmission only over HTTPS.</li>\n<li>Set the SameSite=Strict or Lax attribute on cookies to protect against CSRF.</li>\n<li>Use short-lived access tokens and rotate refresh tokens regularly.</li>\n<li>Implement CSP (Content Security Policy) to reduce XSS risk.</li>\n<li>Avoid storing any tokens in frontend code (e.g., hardcoded in JS files).</li>\n</ol>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>JWT authentication with LoginRadius offers a modern, stateless approach to managing sessions across distributed systems. The IDX integration is ideal for rapid deployment, while the Direct API model is best for organizations needing deep customization and integration flexibility.</p>\n<p>With robust token signing, refresh capabilities, and centralized control, LoginRadius provides a future-ready foundation for secure, scalable identity architecture. <a href=\"https://www.loginradius.com/contact-us?utm_source=blog&#x26;utm_medium=web&#x26;utm_campaign=how-to-integrate-jwt\">Contact us</a> to know more about JWT authentication and implementation guide. </p>\n<h2 id=\"faqs\" style=\"position:relative;\"><a href=\"#faqs\" aria-label=\"faqs permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>FAQs</h2>\n<h3 id=\"1-what-is-jwt-authentication-used-for\" style=\"position:relative;\"><a href=\"#1-what-is-jwt-authentication-used-for\" aria-label=\"1 what is jwt authentication used for permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. What is JWT authentication used for?</h3>\n<p><strong>A:</strong> JWT authentication securely verifies user identities, enabling stateless session management across web, mobile apps, and microservices without server-side session storage.</p>\n<h3 id=\"2-how-does-loginradius-simplify-jwt-integration\" style=\"position:relative;\"><a href=\"#2-how-does-loginradius-simplify-jwt-integration\" aria-label=\"2 how does loginradius simplify jwt integration permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. How does LoginRadius simplify JWT integration?</h3>\n<p><strong>A:</strong> LoginRadius simplifies JWT integration by offering hosted <a href=\"https://www.loginradius.com/docs/single-sign-on/federated-sso/jwt-login/jwt-implementation-guide/\">IDX login pages </a>and direct API-based authentication methods, enabling rapid deployment and deep customization.</p>\n<h3 id=\"3-is-jwt-authentication-secure\" style=\"position:relative;\"><a href=\"#3-is-jwt-authentication-secure\" aria-label=\"3 is jwt authentication secure permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3. Is JWT authentication secure?</h3>\n<p><strong>A:</strong> Yes, JWT authentication is secure when implemented with best practices like short-lived tokens, secure storage methods, signature validation, and refresh token rotation.</p>\n<h3 id=\"4-can-jwt-tokens-be-revoked-with-loginradius\" style=\"position:relative;\"><a href=\"#4-can-jwt-tokens-be-revoked-with-loginradius\" aria-label=\"4 can jwt tokens be revoked with loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>4. Can JWT tokens be revoked with LoginRadius?</h3>\n<p><strong>A:</strong> Yes, LoginRadius allows<a href=\"https://www.loginradius.com/docs/api/v2/customer-identity-api/refresh-token/revoke-refresh-token/?q=revoke+jwt\"> revocation of JWT</a> refresh tokens explicitly, and supports strategies like short-lived tokens and key rotation to manage token lifecycles securely.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"April 15, 2025","updated_date":null,"description":"Discover JWT (JSON Web Token) authentication, its advantages, and how to integrate it seamlessly using LoginRadius' hosted IDX and Direct API methods for secure, scalable identity management.","title":"JWT Authentication with LoginRadius: Quick Integration Guide","tags":["JWT","JSON Web Token","Authentication","Authorization"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":0.7782101167315175,"src":"/static/4cedb7829f98208cbc6d5a9aea4e983d/58556/how-to-integrate-jwt.webp","srcSet":"/static/4cedb7829f98208cbc6d5a9aea4e983d/61e93/how-to-integrate-jwt.webp 200w,\n/static/4cedb7829f98208cbc6d5a9aea4e983d/1f5c5/how-to-integrate-jwt.webp 400w,\n/static/4cedb7829f98208cbc6d5a9aea4e983d/58556/how-to-integrate-jwt.webp 800w,\n/static/4cedb7829f98208cbc6d5a9aea4e983d/1cc9f/how-to-integrate-jwt.webp 896w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Kundan Singh","github":null,"avatar":null}}}},"pageContext":{"limit":6,"skip":24,"currentPage":5,"type":"//engineering//","numPages":53,"pinned":"5c425581-f474-5ae9-abe7-cf5342db2aaa"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}