{"componentChunkName":"component---src-templates-blog-list-template-js","path":"/engineering/5","result":{"data":{"allMarkdownRemark":{"edges":[{"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/d145b262e248d51a28c0d8d8d731e1f2/ee604/4-ways-to-extend-ciam-capabilities.png","srcSet":"/static/d145b262e248d51a28c0d8d8d731e1f2/69585/4-ways-to-extend-ciam-capabilities.png 200w,\n/static/d145b262e248d51a28c0d8d8d731e1f2/497c6/4-ways-to-extend-ciam-capabilities.png 400w,\n/static/d145b262e248d51a28c0d8d8d731e1f2/ee604/4-ways-to-extend-ciam-capabilities.png 800w,\n/static/d145b262e248d51a28c0d8d8d731e1f2/f3583/4-ways-to-extend-ciam-capabilities.png 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><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 51.07692307692307%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAKABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAd1jJKD/xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAEFAl//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAY/Al//xAAYEAEAAwEAAAAAAAAAAAAAAAABABEhEP/aAAgBAQABPyEqZKDAqHf/2gAMAwEAAgADAAAAENPP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGhABAAIDAQAAAAAAAAAAAAAAAQARECFBUf/aAAgBAQABPxAKusrxA4MHAqA00YZ//9k='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Register Route\"\n        title=\"Register Route\"\n        src=\"/static/3bb206a88072e393dc27b5b37720506c/212bf/registerRoute.jpg\"\n        srcset=\"/static/3bb206a88072e393dc27b5b37720506c/6aca1/registerRoute.jpg 650w,\n/static/3bb206a88072e393dc27b5b37720506c/212bf/registerRoute.jpg 768w,\n/static/3bb206a88072e393dc27b5b37720506c/97cd8/registerRoute.jpg 1060w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></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><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 53.69230769230769%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAd1jJKD/xAAXEAEAAwAAAAAAAAAAAAAAAAABEBEg/9oACAEBAAEFAooMf//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABQQAQAAAAAAAAAAAAAAAAAAACD/2gAIAQEABj8CX//EABcQAQEBAQAAAAAAAAAAAAAAAAEAERD/2gAIAQEAAT8hMsIBgBB3/9oADAMBAAIAAwAAABDzz//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABkQAQEBAAMAAAAAAAAAAAAAAAEREAAhUf/aAAgBAQABPxAKNLhII8CcKDO5v//Z'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"login Route\"\n        title=\"login Route\"\n        src=\"/static/0f67758e378cca70ea140a8a70d5e8e7/212bf/loginroute.jpg\"\n        srcset=\"/static/0f67758e378cca70ea140a8a70d5e8e7/6aca1/loginroute.jpg 650w,\n/static/0f67758e378cca70ea140a8a70d5e8e7/212bf/loginroute.jpg 768w,\n/static/0f67758e378cca70ea140a8a70d5e8e7/b1315/loginroute.jpg 1047w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></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><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 55.99999999999999%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAd1jJKD/xAAXEAADAQAAAAAAAAAAAAAAAAAAARAh/9oACAEBAAEFApiFf//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABQQAQAAAAAAAAAAAAAAAAAAACD/2gAIAQEABj8CX//EABcQAQEBAQAAAAAAAAAAAAAAAAEAERD/2gAIAQEAAT8hAsgDACHf/9oADAMBAAIAAwAAABDTz//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABoQAQEBAAMBAAAAAAAAAAAAAAERABAhUfD/2gAIAQEAAT8QRFS6PjRCPAmCDO5z/9k='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"update Route\"\n        title=\"update Route\"\n        src=\"/static/dd7a2de900844aa47a856f4e6812300b/212bf/updateroute.jpg\"\n        srcset=\"/static/dd7a2de900844aa47a856f4e6812300b/6aca1/updateroute.jpg 650w,\n/static/dd7a2de900844aa47a856f4e6812300b/212bf/updateroute.jpg 768w,\n/static/dd7a2de900844aa47a856f4e6812300b/95a07/updateroute.jpg 1042w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></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><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 53.38461538461539%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAd1sJKD/xAAXEAEAAwAAAAAAAAAAAAAAAAABEBEg/9oACAEBAAEFAooMf//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABQQAQAAAAAAAAAAAAAAAAAAACD/2gAIAQEABj8CX//EABcQAQEBAQAAAAAAAAAAAAAAAAEAERD/2gAIAQEAAT8hwsgGAEHf/9oADAMBAAIAAwAAABDTz//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABoQAQADAAMAAAAAAAAAAAAAAAEAESEQMVH/2gAIAQEAAT8QLOyUlQR4FQDQ3n//2Q=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Delete Route\"\n        title=\"Delete Route\"\n        src=\"/static/268e9526fe7fdc3a4de9e847c2b164f6/212bf/deleteroute.jpg\"\n        srcset=\"/static/268e9526fe7fdc3a4de9e847c2b164f6/6aca1/deleteroute.jpg 650w,\n/static/268e9526fe7fdc3a4de9e847c2b164f6/212bf/deleteroute.jpg 768w,\n/static/268e9526fe7fdc3a4de9e847c2b164f6/b1315/deleteroute.jpg 1047w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></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><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 51.07692307692307%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAKABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAd1jJKD/xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAEFAl//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAY/Al//xAAYEAEAAwEAAAAAAAAAAAAAAAABABEhEP/aAAgBAQABPyEqZKDAqHf/2gAMAwEAAgADAAAAENPP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGhABAAIDAQAAAAAAAAAAAAAAAQARECFBUf/aAAgBAQABPxAKusrxA4MHAqA00YZ//9k='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Register Route\"\n        title=\"Register Route\"\n        src=\"/static/3bb206a88072e393dc27b5b37720506c/212bf/Hashedregisterroute.jpg\"\n        srcset=\"/static/3bb206a88072e393dc27b5b37720506c/6aca1/Hashedregisterroute.jpg 650w,\n/static/3bb206a88072e393dc27b5b37720506c/212bf/Hashedregisterroute.jpg 768w,\n/static/3bb206a88072e393dc27b5b37720506c/97cd8/Hashedregisterroute.jpg 1060w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></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><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 53.53846153846153%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAIBBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAe8aSof/xAAXEAEAAwAAAAAAAAAAAAAAAAABEBEg/9oACAEBAAEFAooMf//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABQQAQAAAAAAAAAAAAAAAAAAACD/2gAIAQEABj8CX//EABcQAQEBAQAAAAAAAAAAAAAAAAERABD/2gAIAQEAAT8hhoYBAhp3/9oADAMBAAIAAwAAABBzz//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABoQAQEAAwEBAAAAAAAAAAAAAAEAESExUaH/2gAIAQEAAT8QMnraOfIgcOAYCCbxBN//2Q=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Hashed Login Route\"\n        title=\"Hashed Login Route\"\n        src=\"/static/3a5e61b1165a58a1f43da0efe52aeb37/212bf/hashedloginroute.jpg\"\n        srcset=\"/static/3a5e61b1165a58a1f43da0efe52aeb37/6aca1/hashedloginroute.jpg 650w,\n/static/3a5e61b1165a58a1f43da0efe52aeb37/212bf/hashedloginroute.jpg 768w,\n/static/3a5e61b1165a58a1f43da0efe52aeb37/9ecec/hashedloginroute.jpg 1050w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></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><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 731px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 18.615384615384613%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAEABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAEF/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAH/2gAMAwEAAhADEAAAAcmFgH//xAAVEAEBAAAAAAAAAAAAAAAAAAAQEf/aAAgBAQABBQKv/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFBABAAAAAAAAAAAAAAAAAAAAEP/aAAgBAQAGPwJ//8QAGRAAAQUAAAAAAAAAAAAAAAAAAAEQEWFx/9oACAEBAAE/IcITTf/aAAwDAQACAAMAAAAQ88//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAaEAACAgMAAAAAAAAAAAAAAAAAAREhQVHh/9oACAEBAAE/EJ8C2BK0j//Z'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Crypto\"\n        title=\"Crypto\"\n        src=\"/static/eef145060f999eac67fd7387d3ce3de3/5db71/crypto.jpg\"\n        srcset=\"/static/eef145060f999eac67fd7387d3ce3de3/6aca1/crypto.jpg 650w,\n/static/eef145060f999eac67fd7387d3ce3de3/5db71/crypto.jpg 731w\"\n        sizes=\"(max-width: 731px) 100vw, 731px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></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><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 654px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 20%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAEABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAEF/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAH/2gAMAwEAAhADEAAAAcqFgH//xAAUEAEAAAAAAAAAAAAAAAAAAAAQ/9oACAEBAAEFAn//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAUEAEAAAAAAAAAAAAAAAAAAAAQ/9oACAEBAAY/An//xAAUEAEAAAAAAAAAAAAAAAAAAAAQ/9oACAEBAAE/IX//2gAMAwEAAgADAAAAEHAv/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGRAAAgMBAAAAAAAAAAAAAAAAAAERYZFx/9oACAEBAAE/EG5rhujSk//Z'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Node bcrypt\"\n        title=\"Node bcrypt\"\n        src=\"/static/a33fa24c5b901ff46d96bd719c1a1ba6/22d3c/nodebycrypt.jpg\"\n        srcset=\"/static/a33fa24c5b901ff46d96bd719c1a1ba6/6aca1/nodebycrypt.jpg 650w,\n/static/a33fa24c5b901ff46d96bd719c1a1ba6/22d3c/nodebycrypt.jpg 654w\"\n        sizes=\"(max-width: 654px) 100vw, 654px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></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><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 46.30769230769231%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAAsTAAALEwEAmpwYAAABYklEQVQoz43SPUvDQBwG8NtMsdBFpY4WtbYibXGsxlLfFkEQRfwsTi4ugt/BwVWKUNBRQYQ6OWslUC0qSJpL0mvz9nhXk1Dj68FDDkJ+PPe/EGlyDjEeyU9sooh4RgZJ5nBcOYNYtuPgt+V5XrgnAvgLdF0XGtVhGCYcjtu2HUa881m4HCZSWoYkUB8W+Q6kuo43VYNlWSEm9gEYtCSj8jZSC5sYKKxBSs/38CgoWlHeTtUodA4z1gHrdEMkeF40dJBUcR1jPOPyBjLlLSRnVzHIYZLM94EujDaDSilMxsC6Vg8UcXhD1wd3qgpIYrqE+JR/7B+OLD4yeTunbYgBROIhuBNF6/IZciiaKCg+Orp9we5lAwe1Jg5vmti/fsLe1SPqKvuYczDDoFV/voC8Ye3ZxMldC9UHDecKxWldQ+W+hVfTDufYu+Wh3BKG88sYKawgMbOIWLaMeLb0CbTs//+H70m7F/ZJwLTCAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"LoginRadius - Enter your app name\"\n        title=\"LoginRadius - Enter your app name\"\n        src=\"/static/a89764d477f8e3c676fd91f5cd3eff08/e5715/loginradius.png\"\n        srcset=\"/static/a89764d477f8e3c676fd91f5cd3eff08/a6d36/loginradius.png 650w,\n/static/a89764d477f8e3c676fd91f5cd3eff08/e5715/loginradius.png 768w,\n/static/a89764d477f8e3c676fd91f5cd3eff08/cad6c/loginradius.png 1339w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></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><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 46.98412698412698%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAAsTAAALEwEAmpwYAAABs0lEQVQoz2WSy04bMRiFTdlQFRAI1AUoFJCgUFoUKEhVINxEpC66huYRWsS+qdQn6TvwCCxYs2XXqFK5JGQmmUvG9lxz+tszodHU0tHvsexvzvlt9uJtBS+3PoHNl1A9/4FAuGjc/Ua7dQ+Pc0jf/18yrX72zYXU80bzEWy2uIuF7UMMF4o4+fINCCw45q1W4EuEYYggIPVrEGiFUYz8uH9ogL3aLGP5wxGezW3g9GuNgG245h9I10Acx6mSRCvJqdfrPUmNZqMJNrp6gMn1Y7L6Hp/PvgNJBNN4hG210fU8HSkidzHJz9ypGkWRhihYlKTAn9e3YONvCPjuCGxmA1UCqg0d24WQAbjqlZQwuxKGyAADEfvu4szhxU0zBU4XK2CFLXJYU7vQsWw4bleLcwHDFWhnwCQXs1/VumPbFHllD2Or+9qhityj3pgdm+JyOF1Px245HDeG0D/L9y1dS6fcdcBGlnYwsXb4zyGFUs48cqZ6FYYRPD9E3fKfDuYja1iY4PJXC+z56zKmNj9iaLGUXgoBLYps2w6EELqHSjE9IU7vktOaep/qcgYjewS8qrfwF+cda9cXdcRMAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"LoginRadius API Credentials\"\n        title=\"LoginRadius API Credentials\"\n        src=\"/static/064c243d54fafb448b579eff0beff764/f058b/loginradius1.png\"\n        srcset=\"/static/064c243d54fafb448b579eff0beff764/f058b/loginradius1.png 630w\"\n        sizes=\"(max-width: 630px) 100vw, 630px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></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/2bf56fe9f3665d6ea50e762f073b6531/14b42/coverimage.jpg","srcSet":"/static/2bf56fe9f3665d6ea50e762f073b6531/f836f/coverimage.jpg 200w,\n/static/2bf56fe9f3665d6ea50e762f073b6531/2244e/coverimage.jpg 400w,\n/static/2bf56fe9f3665d6ea50e762f073b6531/14b42/coverimage.jpg 800w,\n/static/2bf56fe9f3665d6ea50e762f073b6531/235b6/coverimage.jpg 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><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 34.61538461538461%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAyUlEQVQoz63Maw7BQBQF4FmfTbAClXYDLALRfViE0MQjbTwiaEq16VNfCeqYmargF4kfX27umTmXCGoHpbraRkPrQlrKEBc9iPMen9KT/FDkgkY7szbElYxav4VKswpyuLgoODBzD9vExGA9wdiYY2ou+VR2KkbUcDPjFF3luZ5ZMK9Ff392YGQ2yAkJShFSBHmEY+LAzrxC6sJiEpfnDNvZW3iLaS999FOO+LcIbxAjpB++4eOjS5GAHmDYUs5fvHaZ58F/+fvBOzTiBOViNs0pAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"An authenticated user&#39;s profile page\"\n        title=\"An authenticated user&#39;s profile page\"\n        src=\"/static/8dcf73e596a6626c34b9787a43e07809/e5715/profile-page.png\"\n        srcset=\"/static/8dcf73e596a6626c34b9787a43e07809/a6d36/profile-page.png 650w,\n/static/8dcf73e596a6626c34b9787a43e07809/e5715/profile-page.png 768w,\n/static/8dcf73e596a6626c34b9787a43e07809/29007/profile-page.png 1600w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></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/cc1040bb014138d9f198e7e127d9c831/ee604/next-authentication.png","srcSet":"/static/cc1040bb014138d9f198e7e127d9c831/69585/next-authentication.png 200w,\n/static/cc1040bb014138d9f198e7e127d9c831/497c6/next-authentication.png 400w,\n/static/cc1040bb014138d9f198e7e127d9c831/ee604/next-authentication.png 800w,\n/static/cc1040bb014138d9f198e7e127d9c831/f3583/next-authentication.png 1200w,\n/static/cc1040bb014138d9f198e7e127d9c831/5707d/next-authentication.png 1600w,\n/static/cc1040bb014138d9f198e7e127d9c831/eeb1b/next-authentication.png 1920w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Emadamerho-Atori Nefe","github":"nefejames","avatar":null}}}},{"node":{"excerpt":"In this post, I’ll talk about how cookies compare to browser storage. You’ll understand why cookies came out, the problem they solve, and…","fields":{"slug":"/engineering/guest-post/local-storage-vs-session-storage-vs-cookies/"},"html":"<p>In this post, I’ll talk about how cookies compare to browser storage. You’ll understand why cookies came out, the problem they solve, and their limitations.</p>\n<p>Then you’ll explore what browser storage is, and dive deeper into local storage and session storage. You’ll look at their features, where they can be useful, and how to use them via JavaScript.</p>\n<p>You’ll then see how you can contrast the features, advantages, and disadvantages of each and also highlight specific use cases of each.</p>\n<p>You’ll also look at the best practices or approach to keep in mind while using each of them and the best place to store your JWT or auth tokens.</p>\n<hr>\n<p>How many times have you seen a popup on a website that says:</p>\n<blockquote>\n<p>This website is using cookies to store your information.</p>\n</blockquote>\n<p>I'm guessing so often that you've lost the count!</p>\n<p>Cookies have been used since time immemorial for storing session related information of a user. This allows websites to provide a unique and engaging experience to their users.</p>\n<p>However, cookies can be a bit difficult to use, have limited use-case, and have small data storing capacity. To combat this, modern browsers come with their own storage mechanisms like local storage and session storage.</p>\n<p>In this post, I’ll talk about these storage mechanisms. You'll understand how local storage, session storage, and cookies compare against one another and explore common use cases of each. By the end of this post, you'll know exactly when to use which.</p>\n<h2 id=\"a-brief-history-of-cookies\" style=\"position:relative;\"><a href=\"#a-brief-history-of-cookies\" aria-label=\"a brief history of cookies 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>A Brief History of Cookies</h2>\n<p>Let's have a refresher on the history of cookies.</p>\n<p>Back in the day, websites used HTTP protocol which is <em>stateless</em>. This meant that they couldn't store user-related information like the user’s session id, the name of the user, etc., in the browser.</p>\n<p>As the web advanced and grew more popular, websites started storing user related information in the browser itself. This helped them differentiate what kind of user is interacting with their website and provide a personalized experience to the user.</p>\n<h3 id=\"enter-cookies\" style=\"position:relative;\"><a href=\"#enter-cookies\" aria-label=\"enter cookies 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>Enter Cookies</h3>\n<p>That's how cookies were born. They presented a mechanism to store lightweight client or server side data on the browser as key value pairs. They also had an expiry timestamp after which they were automatically deleted by the browser.</p>\n<p>Also, both browser and the server could set and retrieve cookies from a user’s browser. Moreover, these cookies were sent alongside each HTTP request automatically. This came in handy for server side websites at a time when single page applications weren't a thing. They could easily discern a user's information with each HTTP request that user made.</p>\n<h2 id=\"the-rise-of-browser-storage\" style=\"position:relative;\"><a href=\"#the-rise-of-browser-storage\" aria-label=\"the rise of browser storage 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>The Rise of Browser Storage</h2>\n<p>Where cookies solved a great problem, it had some limitations. First, they could only store data up to a few kbs. As client-side applications became more complex, there was a need to store more complex data in the browser.</p>\n<p>With the onset of HTML5, websites were introduced to browser storage APIs for storing client side information. These APIs were available on browser's window objects globally. Thus, any JavaScript running in the browser could easily access them. The major differentiator was that they had higher data storage capacity and could only be accessed by client-side JavaScript.</p>\n<p>Browsers rolled out two storage mechanisms — local storage and session storage. So let's explore and understand them in detail.</p>\n<h2 id=\"browsers-session-storage\" style=\"position:relative;\"><a href=\"#browsers-session-storage\" aria-label=\"browsers session storage 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>Browser’s Session Storage</h2>\n<p>Let's first take a peek at where the session storage resides in the browser:</p>\n<ol>\n<li>\n<p>Open the developer tools in the browser and head over to the \"Application\" tab.</p>\n<p><img src=\"/6322f4dfe998ff0adaa9b8ee847c80ec/application-tab-screenshot.png\" alt=\"Application Tab Screenshot\"></p>\n</li>\n<li>\n<p>Under the storage section, you'll find a section named \"Session Storage\".</p>\n<p><img src=\"/d1d9b02e5a20551b8e2dd9cb909c8588/session-storage-tab-screenshot.png\" alt=\"Session Storage Section Screenshot\"></p>\n</li>\n<li>Click on it, and you'll be able to see the session storage for that website.</li>\n</ol>\n<p>There it is! Now, let's look at the features of browser's session storage.</p>\n<h3 id=\"storage-capacity\" style=\"position:relative;\"><a href=\"#storage-capacity\" aria-label=\"storage capacity 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>Storage Capacity</h3>\n<p>Session storage can store data ranging between 5mb - 10mb. The exact amount of storage capacity varies as per each browser's implementation, but it's a lot more than 4kb of storage capacity cookies offer!</p>\n<h3 id=\"data-persistence\" style=\"position:relative;\"><a href=\"#data-persistence\" aria-label=\"data persistence 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>Data Persistence</h3>\n<p>As the name suggests, session storage only persists the data as long as a browser tab is opened. This means that each time you open a new tab or a new browser window, a new session storage is created. So any data you store inside the session storage will automatically get deleted when you close that tab/window.</p>\n<h3 id=\"using-session-storage\" style=\"position:relative;\"><a href=\"#using-session-storage\" aria-label=\"using session storage 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>Using Session Storage</h3>\n<p>You can access the session storage in the <code>window</code> object:</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=\"mtk12\">window</span><span class=\"mtk1\">.</span><span class=\"mtk12\">sessionStorage</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//Storage {length: 0}</span></span></code></pre>\n<p>This would return the length of the session storage along with an object representing the data that's currently present inside. Since it's empty to begin with, the length is 0. Note that you may directly access the <code>sessionStorage</code> object as well.</p>\n<h4 id=\"adding-data\" style=\"position:relative;\"><a href=\"#adding-data\" aria-label=\"adding 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>Adding Data</h4>\n<p>Let's add a key-value pair to the session storage using the <code>setItem</code> function available in the <code>sessionStorage</code> object:</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=\"mtk12\">sessionStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;id&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;123&quot;</span><span class=\"mtk1\">)</span></span></code></pre>\n<p>This will set a new item in the session storage with the key <code>id</code> and value <code>123</code>. If you simply invoke the <code>sessionStorage</code> object now:</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\">sessionStorage</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//Storage {id: &#39;123&#39;, length: 1}</span></span></code></pre>\n<p>You now get your recently added data back!</p>\n<p>You'll also see this inside the session storage section of the browser's application tab:</p>\n<p><img src=\"/a536d2cf8d666e60cd9dc0936adf8090/session-storage-example-1.png\" alt=\"Session Storage Example\"></p>\n<h4 id=\"inserting-complex-json-data\" style=\"position:relative;\"><a href=\"#inserting-complex-json-data\" aria-label=\"inserting complex json 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>Inserting Complex JSON Data</h4>\n<p>Let's add a bit more complex JSON object in the session storage that looks like this:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">data</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=\"mtk8\">&quot;61c6c1df7cda7d370a9ef601&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">index:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">guid:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;13672f0e-f693-4704-a6f9-839ff36e8960&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">isActive:</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\">balance:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;$3,602.49&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">picture:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;http://placehold.it/32x32&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">age:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">25</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">friends:</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\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Adkins Coleman&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=\"mtk12\">id:</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 class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Howe Douglas&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=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">2</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Becky Velez&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>You'll first need to <em>stringify</em> it since the value against a key can only be a string. Then, you'll store it inside the session storage using the <code>setItem</code> method:</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=\"mtk12\">sessionStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;user_data&quot;</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\">data</span><span class=\"mtk1\">))</span></span></code></pre>\n<p>It should now appear inside the session storage of the browser's application tab:</p>\n<p><img src=\"/841be8af005e05920607f66cddfbf745/session-storage-example-2.png\" alt=\"Complex JSON Data in Session Storage Example\"></p>\n<p>Awesome! Let's take a look at retrieving this data.</p>\n<h4 id=\"retrieving-data\" style=\"position:relative;\"><a href=\"#retrieving-data\" aria-label=\"retrieving 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>Retrieving Data</h4>\n<p>You can use the <code>getItem()</code> function to retrieve a value stored against a key from the session storage by specifying the key as the first parameter in the function.</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=\"mtk12\">sessionStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;id&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//&#39;123&#39;</span></span></code></pre>\n<p>If you're retrieving an object, you'll need to use <code>JSON.parse</code> first to convert the string into a JavaScript object:</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=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">parse</span><span class=\"mtk1\">(</span><span class=\"mtk12\">sessionStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;user_data&quot;</span><span class=\"mtk1\">))</span></span></code></pre>\n<h3 id=\"usecase\" style=\"position:relative;\"><a href=\"#usecase\" aria-label=\"usecase 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>Usecase</h3>\n<p>Since data in session storage persists only across a browser tab, there are some unique usecases for session storage.</p>\n<h4 id=\"booking-applications\" style=\"position:relative;\"><a href=\"#booking-applications\" aria-label=\"booking applications 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>Booking Applications</h4>\n<p>Session storage can be used in multi-step processes that must be performed in a single instance. This includes booking flights, hotels, movie tickets, train reservations etc. You can store the details of the previous steps in the browser's session storage to prepopulate those forms or inputs.</p>\n<p>Since these are critical activities that must be performed in a single go, the data will automatically get deleted when the user jumps to a new tab or a new browser window.</p>\n<h4 id=\"prompting-loginsignups-to-a-user\" style=\"position:relative;\"><a href=\"#prompting-loginsignups-to-a-user\" aria-label=\"prompting loginsignups to a 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>Prompting Login/Signups to a User</h4>\n<p>Blogging websites, newsletters, tutorial websites etc., have tons of visitors who read through the content without creating an account. In such scenarios, you can subtly prompt the user every time they visit the website to create an account. You can track the session of each user in the session storage.</p>\n<p>Every time a user reads a blog post or an article on a different tab, you can ask them to create an account. This could be a great way to offer a non-blocking experience for your users whilst effectively converting them to a signed-up user for your website.</p>\n<h2 id=\"browsers-local-storage\" style=\"position:relative;\"><a href=\"#browsers-local-storage\" aria-label=\"browsers local storage 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>Browser’s Local Storage</h2>\n<p>Under the application tab where session storage resides, you'll find a section called local storage right underneath it.</p>\n<p><img src=\"/6b873e80fdedd356fdc792765cbed627/local-storage-tab-screenshot.png\" alt=\"Local Storage Tab Screenshot\"></p>\n<p>That's where you can see everything you store inside the local storage of your browser. Local storage works, appears, and similar to session storage. For instance, just like Session storage, local storage can also store data ranging between 5mb - 10mb depending upon a browser's implementation.</p>\n<h3 id=\"data-persistence-1\" style=\"position:relative;\"><a href=\"#data-persistence-1\" aria-label=\"data persistence 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>Data Persistence</h3>\n<p>Unlike session storage where data is automatically deleted when a browser tab or window is closed, data in local storage has no default expiry. It's only deleted if you manually delete that data from the local storage either directly, via browser settings, or through your JavaScript code.</p>\n<p>That means that data in a local storage persists even after a particular tab or browser window is closed.</p>\n<h3 id=\"using-local-storage\" style=\"position:relative;\"><a href=\"#using-local-storage\" aria-label=\"using local storage 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>Using Local Storage</h3>\n<p>You can add and retrieve data from local storage in the same way you perform those operations with session storage. The only change is now you'll have to use the <code>localStorage</code> object to perform these operations instead.</p>\n<p>For instance, you can add an item to the <code>localStorage</code>, as follows:</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=\"mtk12\">localStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;id&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;123&quot;</span><span class=\"mtk1\">)</span></span></code></pre>\n<p>Consequently, you can retrieve an item using the <code>getItem()</code> function:</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=\"mtk12\">localStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;id&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//&#39;123&#39;</span></span></code></pre>\n<h3 id=\"usecase-1\" style=\"position:relative;\"><a href=\"#usecase-1\" aria-label=\"usecase 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>Usecase</h3>\n<p>Local storage has a number of uses due to the fact that data inside it has no default expiry. Think about all those scenarios where you want to store some global data that's accessed often in your application.</p>\n<h4 id=\"generic\" style=\"position:relative;\"><a href=\"#generic\" aria-label=\"generic 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>Generic</h4>\n<p>For instance, your user's email id, username, full-name, etc. All these data are widely used throughout different pages of your application. Storing this data inside the local storage will help you prevent unwanted API calls to the server to fetch this data. Also, since this data isn't normally changed often, the chances of having inconsistent data across the browser and the server is quite low.</p>\n<h4 id=\"application-specific\" style=\"position:relative;\"><a href=\"#application-specific\" aria-label=\"application specific 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>Application Specific</h4>\n<p>You can also use it to store application specific data that is immutable throughout a login session of a user. For instance, if you have an ecommerce site, you can store the preferred payment option of the user, default delivery addresses, etc. You can also store user preferences such as the theme a user prefers for your website (dark or light mode).</p>\n<h2 id=\"cookies-vs-browser-storage\" style=\"position:relative;\"><a href=\"#cookies-vs-browser-storage\" aria-label=\"cookies vs browser storage 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>Cookies vs. Browser Storage</h2>\n<p>Now that you've understand how browser storage works, you can compare them effectively against cookies. However, let's first look at their similarities.</p>\n<h3 id=\"similarities\" style=\"position:relative;\"><a href=\"#similarities\" aria-label=\"similarities 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>Similarities</h3>\n<p>Remember in the beginning I asked you how many times you've seen that cookies popup? Most of these popups also have an option where you can choose not to accept these cookies.</p>\n<p>In other words, cookies are <em>blockable</em> by users and so is browser storage. Users can choose not to allow their data to be stored via any of these mechanisms — and hence, your application should never completely rely on these storage mechanisms.</p>\n<p>Both cookies and browser storage store key-value pairs as strings and are well supported in all modern browsers. The data inside this can also be easily edited by the user.</p>\n<h3 id=\"differences\" style=\"position:relative;\"><a href=\"#differences\" aria-label=\"differences 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>Differences</h3>\n<p>You know that browser storage has a greater storage capacity than cookies. Hence, browser storage is always a better choice than cookies to store large client-side data.</p>\n<p>However, since session storage and local storage have different data persistence, you should carefully choose either of them depending on how long you want the data to persist.</p>\n<p>Cookies allow you to automatically set a TTL or expiry time; are transferred with every HTTP request to the server; and, can also be accessed by the server. These features are missing in browser storage. Which brings us to the question — where would cookies be actually more useful than browser storage?</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 75.07692307692308%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADQklEQVQ4y3WT+29TZRjH+8f4n6i/0I0YoS2bISEhuhB/gTDjD2IEXaJkuIyhXNYYZWO3tsLYkKAE4wUIY4LANrfgtpb19HJOe3pZ23Pv+fi0ndNEeZNv3tt5P8/3eZ/zBqz8FC+TmZukWYzh5cdw8hNY6hToHXmFzr6tTeOV4riFmfaZwMtALbnycfLpRUZmEyw+lsOZMeaunyc6c4Hlhcs0SzMU16Is3zzJxqNz7YD/CzSykyBRVxdH+HLwEB8Pn2Dj+TS15Dcc/egUrxw8wnh0EGpxVuY+5N6Zg9ydeo96ZoKAmZsQN+P/0pU2sKnHSS6NMvDJERLj70M1QTk9xRdDpzj29mFuzJ4T4FWUJ+dZvHyU5C+nMSWjgKUmsAo3sLT5Tl+Y76SdHcNVv6KSvEBDiWLnolhbozQ2L1LbvISZuoSdiuKsj2I+l/G67GeuEHCrC7RaNqtQLpVk5GLpd3C0Seqrh8g/DJF5EKb4JIJ9vxclFkabDbOVCGN8KxrqJjUQxPi8C2d5RByW7lOrm9Trdba3t7FtS6BNfEeFF+9gre2nvhLB2zgAC724tyLUvwtj/SDzuRAMd2GcCeINBXGWBGjq99BLFXS9KNIxTaPt2HcrsNXH9tI+Co/CHeDDXpxbB9CuhTC+l/l8GM52UzwtsKEdhy1gUa9Iyllc123Dmn4LWGoDbXFYW46I2x78B71wu4fyXJjmnR5x2AGWBej+DWwUfqVQKKFpqkhDUdKomi5UcfiiD+OP/VSeCjDVAfqSqn49hLcD9IfF4Wd7/nFoiMNKtU6lUqZarVIuC1wC6Npm+w6b6yHMVUkvveNQQI2bEuCnHYcj3dQGg+273HWoqgU0NU8+l5XitArjYRt5nI0+qfK+dpW3pTAsvoU+G0GJhyjOy1xUGuwi92kQVWS1imKVFzBMaBhOW65Hp/l1/ORhNn/ew+ptcbHyplQ5RGp8L2tfd7MxsRf/6htUBl7nzw9eRT35Gs6zswSc0o/g5PDtNNgKTWsLz1TwGqs00ydAOQaZfnzlON6z4/Cb6HE//N6Pd1f2rr27K1t+8M7Tk1fxH7WeYT6GkYuLYjKOY6oyVmO7MjVZK8paodOb6jR/AZKN6VZCYGrbAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Comparison Table of Local Storage Session Storage and Cookies\"\n        title=\"Comparison Table of Local Storage Session Storage and Cookies\"\n        src=\"/static/a6522d000e0137d5fdf82fd370646d12/e5715/comparison-table.png\"\n        srcset=\"/static/a6522d000e0137d5fdf82fd370646d12/a6d36/comparison-table.png 650w,\n/static/a6522d000e0137d5fdf82fd370646d12/e5715/comparison-table.png 768w,\n/static/a6522d000e0137d5fdf82fd370646d12/2bef9/comparison-table.png 1024w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>The answer is server side data! If you've dealt with authentication before, you know that at some point you need to store the authentication token or JWT of a user somewhere where it's easily accessible. That's where cookies are helpful. But why can't we use or why shouldn't we use browser storage here?</p>\n<h2 id=\"storing-your-jwtauth-token\" style=\"position:relative;\"><a href=\"#storing-your-jwtauth-token\" aria-label=\"storing your jwtauth token 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>Storing Your JWT/Auth Token</h2>\n<p>Data such as JWT or Auth token should not be stored in browser storage because they can be accessed by any client side JavaScript running in the browser. This means that if your application somehow leaves an XSS vulnerability, your user's authentication token could be easily leaked to the attacker.</p>\n<p>The attacker could then make false requests, modify your user's data in the database, and do a lot of damage for your application as well as users. Hence, it's always best to store JWTs in http only cookies. Http only cookies are special cookies that cannot be accessed by client side JavaScript. This way they're secure against XSS attacks.</p>\n<p>Also, authentication token is often refreshed on expiry and one can use cookies TTL easily to manage that. For simpler cases, one can also store JWT inside regular cookies by setting a TTL.</p>\n<p>But all in all, authentication itself can be a tricky subject. If you're looking for a no-code identity platform that can seamlessly handle authentication for your application, consider using <a href=\"https://www.loginradius.com/\">LoginRadius</a>.</p>\n<h2 id=\"wrapping-it-up\" style=\"position:relative;\"><a href=\"#wrapping-it-up\" aria-label=\"wrapping it up 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>Wrapping it Up</h2>\n<p>Now that you understand how powerful browser storage is, don't feel shy to use it in your applications. Use cookies for server side data where you need a TTL, session storage for specific use cases discussed above, and local storage to manage global data in your application.</p>\n<p>However, avoid the pattern where your single page application directly interacts with the local storage. For instance, if you're using React with Redux to manage the state in your application, let your reducers take control over what goes and comes out of local storage. Your React components should be abstracted from using local storage directly.</p>\n<p>Finally, since local storage data has no default expiry, be vary of when you're clearing this data to avoid data inconsistency between your frontend and backend.</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 .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n</style>","frontmatter":{"date":"January 12, 2022","updated_date":null,"description":"This article helps you understand the differences between browser storage and cookies. By the end, you'll understand when to use cookies and browser storage (both local storage and session storage).","title":"Local Storage vs. Session Storage vs. Cookies","tags":["Cookie","Browser Storage","Authentication","JWT"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/05c0a6d7a4539d8f04241b6ddf720a52/ee604/blog-banner.png","srcSet":"/static/05c0a6d7a4539d8f04241b6ddf720a52/69585/blog-banner.png 200w,\n/static/05c0a6d7a4539d8f04241b6ddf720a52/497c6/blog-banner.png 400w,\n/static/05c0a6d7a4539d8f04241b6ddf720a52/ee604/blog-banner.png 800w,\n/static/05c0a6d7a4539d8f04241b6ddf720a52/f3583/blog-banner.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Siddhant Varma","github":"FuzzySid","avatar":null}}}},{"node":{"excerpt":"All React developers love to leverage the benefits React caters to in developing web applications. But developers need to keep in mind the…","fields":{"slug":"/engineering/react-security-vulnerabilities/"},"html":"<p>All React developers love to leverage the benefits React caters to in developing web applications. But developers need to keep in mind the security postures while creating React web apps. React applications face a vast attack surface and are prone to different vulnerabilities. This article is a checklist of React security best practices that every developer should know before diving into PWA (progressive web application) development.\nIf you are new to progressive web applications and React, let's get familiar with these terminologies first.</p>\n<h2 id=\"what-are-progressive-web-applications-pwa\" style=\"position:relative;\"><a href=\"#what-are-progressive-web-applications-pwa\" aria-label=\"what are progressive web applications pwa 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 are Progressive Web Applications (PWA)?</h2>\n<p>Progressive Web Apps (PWA) are apps built using web technologies like HTML, CSS, and JavaScript (JS). But these apps deliver the experience, feel, and functionality of a native app. PWA combines new technologies and integrations to build a reliable, engaging, accessible, and secure application. Developers mostly use React on top of HTML and JavaScript to build a progressive web app.</p>\n<h2 id=\"what-is-react\" style=\"position:relative;\"><a href=\"#what-is-react\" aria-label=\"what is react 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 React?</h2>\n<p>React is popular among progressive web app developers. This open-source, robust JavaScript library helps in building user interfaces based on UI components. React gains popularity in the software development industry because it allows developers to create lightweight apps with additional facilities: security, push notification, app-like look and feel, etc. Some popular companies that have become the early adopters of React are Instagram, Netflix, Airbnb, Uber Eats, Discord, the New York Times, etc. </p>\n<h2 id=\"security-vulnerabilities-in-react-and-how-to-prevent-them\" style=\"position:relative;\"><a href=\"#security-vulnerabilities-in-react-and-how-to-prevent-them\" aria-label=\"security vulnerabilities in react and how to prevent them 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>Security Vulnerabilities in React and How to Prevent Them</h2>\n<p>React helps developers build a reliable, robust, and secure progressive web app, but these apps face certain security pitfalls also. Developers need to give prior attention to security vulnerabilities, which are often ignored due to faster app development cycles or more focus on product features.\nWith the arrival of each new update in React having more features, the security flaws are getting unnoticed. Such unnoticed actions are increasing security concerns. Here is a list of top React security vulnerabilities that every React developer must address before delivering or deploying their apps.</p>\n<h2 id=\"sql-injection\" style=\"position:relative;\"><a href=\"#sql-injection\" aria-label=\"sql injection 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>SQL Injection</h2>\n<p>SQL Injection (SQLi) is a widely known web application attack. The cybercriminal intends to perform database manipulation logically to access sensitive information that is not supposed to be displayed. Attackers try to sneak into that sensitive information to collect phone numbers, payment details, addresses, passwords, and other credentials.\nThis technique allows the attackers to manage access to the server, pull the data, and manipulate the values in the database. Apart from data modification, hackers can also delete the data.\nLet us take an example. Let us take an example where the code will search for the current user-ID and the login matching the employee name, where the owner is the current user-ID.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">string query = &quot;SELECT * FROM logondata WHERE owner = &quot;&#39;&quot;</span>\n<span class=\"grvsc-line\">+ empID + &quot;&#39; AND empName = &#39;&quot;</span>\n<span class=\"grvsc-line\">+ EmpName.Text + &quot;&#39;&quot;;</span></code></pre>\n<p>Combining both the employee ID and employee name, the following query gets generated.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">SELECT * FROM logondata</span>\n<span class=\"grvsc-line\">WHERE owner =</span>\n<span class=\"grvsc-line\">AND empName = ;</span></code></pre>\n<p>The problem that pops here is that the main code leverages the concept of concatenation that helps in combining those data. The attacker can use a string like <code> 'empName' OR 'x'='x' </code> as the employee name. <code> 'x' = 'x' </code> is such a condition, which will always evaluates to True. Therefore, the statement returns True for all values within the table. So, the following query becomes:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">SELECT * FROM logondata</span>\n<span class=\"grvsc-line\">WHERE owner = &#39;karlos&#39;</span>\n<span class=\"grvsc-line\">AND empName = &#39;name&#39; OR &#39;x&#39; = &#39;x&#39;;</span></code></pre>\n<p>There are three major categories of SQL injection based on how attackers gain access to the backend data.</p>\n<ul>\n<li>\n<p><strong>In-band SQL Injection:</strong> Here the persuader will instigate the attack and gather sensitive credentials via one single channel. Such SQL attacks are simple, and hence, it is one of the most commonly performed SQLi attacks on React apps. It comes with two sub-categories –</p>\n<ul>\n<li><strong>Error-based SQLi:</strong> The attacker performs a fake mimicking of the admin's credentials. Such an action provokes the database to generate an error. This error message reflects how the database schema and its structure got designed.</li>\n<li><strong>Union-based SQLi:</strong> The attacker uses the UNION operator of SQL to perform this attack. Using UNION, the attacker fuses multiple SELECT statements and triggers them from the web app for an HTTP response. Attackers can conduct a successful attack if the data response fetches some sensitive data residing in the database. It proves that UNION-based SQLi is possible.</li>\n</ul>\n</li>\n<li>\n<p><strong>Inferential/Blind SQL Injection:</strong> The attacker pushes payloads targeting the server. Then they observe the behavior and keep track of the server response to know more about the database structure. Here, the attacker cannot witness the data reverting through the attack in-band, hence the name \"Blind.\" There are two sub-categories of blind SQLi.</p>\n<ul>\n<li><strong>Boolean:</strong> The persuader sends an adversary query to the target database initiating the app to respond back. Depending on the True or False response value, the cybercriminal can prepare another SQL query that can extract data from that target database. The result of the query is either True or False and hence the name.</li>\n<li><strong>Time-based:</strong> Here, the attacker sends a SQL query through the web app and waits for the response. The attacker records the time required by the database in responding back and checks the server response as well (True or False). Based on these two response parameters, the attacker re-launches another query. If the message sent through the SQL query successfully slows down the response, SQL injection is possible on that application.</li>\n</ul>\n</li>\n<li><strong>Out-of-Band SQL Injection:</strong> Such attacks are more likely when the attacker senses some particular feature enabled in the server used by the React web application. This attack happens when the attacker cannot use the same channel to launch the attack and fetch data. They use such attack vectors when the server is unstable or unable to respond promptly.</li>\n</ul>\n<h3 id=\"checklist-to-fix-sqli-vulnerability-in-react-apps\" style=\"position:relative;\"><a href=\"#checklist-to-fix-sqli-vulnerability-in-react-apps\" aria-label=\"checklist to fix sqli vulnerability in react apps 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>Checklist to Fix SQLi Vulnerability in React Apps</h3>\n<ul>\n<li>A developer must follow the principle of rendering the least privilege to all accounts that will connect through a SQL query to the database.</li>\n<li>It is always necessary to filter all sorts of user input by following a strict whitelist. Even when an internal user provides any SQL query as input, the React app should filter those incoming SQL queries.</li>\n<li>A progressive web app becomes a victim of SQLi when a developer gives its database connection access to privileges like INSERT, UPDATE, or DELETE. So, developers should follow the best practice by assigning accurate database roles to separate account types.</li>\n<li>There could be some external factors (such as an external library, API, or software) that might drag your React application to a vulnerable position. To protect your React app from such vulnerability, the development team should scan the app periodically through any vulnerability scanner like Nessus or Acunetix.</li>\n<li>APIs connected to the React app can pose a threat to a significant level. Thus, a robust approach to avoid SQLi on React apps is to verify all API functions associated with their API schemas.</li>\n<li>Developers can place a REST API between the front-end (React code) and the back-end (database). It will create an extra layer of security that will not allow the front-end users to execute any SQL query directly. It prevents the React app from SQL injection attacks.</li>\n</ul>\n<h2 id=\"cross-site-scripting-xss-vulnerabilities\" style=\"position:relative;\"><a href=\"#cross-site-scripting-xss-vulnerabilities\" aria-label=\"cross site scripting xss vulnerabilities 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>Cross-Site Scripting (XSS) Vulnerabilities</h2>\n<p>The comprehensive rendering feature of React makes it a preferable choice over other JavaScript libraries and frameworks. But this rendering feature also drags React-based apps to the most widely exploited vulnerability, cross-site scripting (XSS). Cross-site scripting leverages malicious client-side scripts by injecting them into web applications. When the users trigger those scripts, the attackers gain control over the app and steal sensitive information from the web application. </p>\n<p>Injecting malicious scripts into the react app will make the app release some internal app data. Therefore, React developers should prevent the application from running the script. Here is a typical example of cross-site scripting where the attacker can place and execute a malicious script within the application like this:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&lt;input type=&quot;search&quot; value=&quot;PWA&quot;/&gt;</span></code></pre>\n<p>Now, executing malicious script will make the search look like:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&lt;input type=&quot;search&quot; value=&quot;Attacker &quot;/&gt; &lt;script&gt; StealCredentials() &lt;/script&gt;&quot;&gt; ;</span></code></pre>\n<p>Here, StealCredentials() is a function that contains malicious scripts to steal user information.\nLet us now take a look at the types of XSS.</p>\n<ul>\n<li><strong>Reflected (Non-persistent) XSS:</strong> In this common type of XSS invasion, the attacker pushes phishing emails, malicious links or uses different hacking techniques to outwit victims to send malicious requests to the server. So, if the application is not leveraging a decent escaping method to user-provided data, the reflected XSS payload gets executed to the user's browser.</li>\n<li><strong>Stored (Persistent) XSS:</strong> It is the most damaging XSS attack form that stores the payload somewhere on the server-side. The attacker uses that payload or malicious script (mostly a JavaScript code) into the target React application. If the application does not render any input validation, the malicious code gets stored permanently (persistent) within the database. Popular web application areas where attackers try this attack are in the blog comment box or a forum post.</li>\n<li><strong>DOM-based XSS:</strong> Attackers can implement such XSS invasion when the web application follows the Document Object Model (DOM) structure. A progressive web app leveraging the principle of DOM stores the data on the client-side. The browser has to read and display the output from that stored data. In DOM-based XSS, the attacker injects the malicious code or payload in the DOM and hence the name. The attack mechanism executes the injected payload when users read the data back from the DOM.</li>\n</ul>\n<h3 id=\"checklist-to-fix-xss-vulnerability-in-react-apps\" style=\"position:relative;\"><a href=\"#checklist-to-fix-xss-vulnerability-in-react-apps\" aria-label=\"checklist to fix xss vulnerability in react apps 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>Checklist to Fix XSS Vulnerability in React Apps</h3>\n<p>This attack gains popularity, not simply because of its potential to harm the target users through the application but because such attacks need more creative and intellectual hackers. But, to prevent such attacks, developers need to become even more creative.</p>\n<ul>\n<li>The easiest way of securing any React app from multiple XSS attacks is to employ WAF (Web Application Firewall) with the code. WAF leverages a concept called signature-based filtering to restrict cross-site scripting attacks. React developers can incorporate a web application firewall into their code for protecting the app from running any adversary script.</li>\n<li>Developers can also disable the markups through which attackers can perform external code execution on React app. Some well-known HTML elements that allow running scripts are: &#x3C;script>, &#x3C;link>, &#x3C;object>, and &#x3C;embed>.</li>\n<li>Various programming languages offer libraries that can enable parsing HTML formatted text. These libraries can help sanitize HTML markup easily to prevent React apps from XSS. OWASP also has a range of libraries such as HtmlSanitizer, Java HTML Sanitizer, etc.</li>\n<li>Developers can also protect React apps from XSS by performing blacklist validation in conjunction with URL parsing.</li>\n<li>Modern and updated browsers (like Google Chrome) come with XSS detection and will not allow attackers to run any malicious script that is not coming from the original server or source.</li>\n<li>React developers can also prevent XSS by adding one security check by leveraging <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS\">Cross-Origin Resource Sharing (CORS)</a>. They have to use it in the code header and assign it 'True'. It uses the browser's same-origin policy and blocks reading a resource originating from a different origin. Using CORS, developers can stop a malicious site from reading another site's data.</li>\n<li>\n<p>You can also use content security policies as the last line of defense against XSS. If all other XSS prevention fails, CSP allows developers to control various things, such as loading external scripts and executing inline scripts. To deploy CSP, developers need to include an HTTP response header called Content-Security-Policy with a value carrying the policy.\nAn example for including CSP is as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">default-src &#39;self&#39;; script-src &#39;self&#39;; object-src &#39;none&#39;; frame-src &#39;none&#39;; base-uri &#39;none&#39;;</span></code></pre>\n</li>\n</ul>\n<h2 id=\"broken-authentication\" style=\"position:relative;\"><a href=\"#broken-authentication\" aria-label=\"broken 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>Broken Authentication</h2>\n<p>Broken authentication is a weakness through which attackers can capture one or multiple accounts when authentication or session management is poorly implemented in progressive web apps. This vulnerability helps the attacker take over multiple user accounts, letting the attacker possess the same privileges and access control as the target user. </p>\n<p>Attackers usually exploit such a React security vulnerability by detecting the authentication solution or bypassing them. The security team labels the authentication as broken when the cybercriminal can compromise users' passwords, session tokens, digital identities, or account information from the React app. Examples of some common reasons for this attack are:</p>\n<ul>\n<li>Unencrypted network sending session IDs, passwords, and other credentials</li>\n<li>Unprotected authentication credentials</li>\n<li>Session values without a specific time-out</li>\n<li>Predictable login credentials</li>\n<li>Improper hashing and salting of passwords</li>\n</ul>\n<p>Let us take a situation where the attacker could detect the hashes for the following names.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">Sue    4420d1918bbcf7686defdf9560bb5087d20076de5f77b7cb4c3b40bf46ec428s</span>\n<span class=\"grvsc-line\">Karlos    4420d1918bbcf7686defdf9560bb5087d20076de5f77b7cb4c3b40bf46ec624g</span>\n<span class=\"grvsc-line\">Dee    77b177de23f81d37b5b4495046b227befa4546db63cfe6fe541fc4c3cd216egk</span></code></pre>\n<p>The hash function will store the password in a hashed form rather than plain text. But then, humans can easily read the hash. Now, if two different users enter the same password, then these passwords will generate the same hash. Hackers can perform a dictionary attack, and if they crack one password, they can use the same password to gain access to other accounts that use the same hash.</p>\n<h3 id=\"checklist-to-fix-react-pwas-from-broken-authentication-vulnerability\" style=\"position:relative;\"><a href=\"#checklist-to-fix-react-pwas-from-broken-authentication-vulnerability\" aria-label=\"checklist to fix react pwas from broken authentication vulnerability 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>Checklist to Fix React PWAs from Broken Authentication Vulnerability</h3>\n<ul>\n<li>The React applications should enforce password checks, whether the password is strong or weak. Also, adding criteria like eight characters (minimum) having uppercase, lowercase, numbers, and symbols can prevent users from such attacks.</li>\n<li>Employing multi-factor authentication (MFA) can prevent users from compromised credential reuse and credential stuffing.</li>\n<li>Another common React security best practice is to generate the message or notification email, keeping the email format or template the same. Such a practice prevents React app users from account enumeration attacks.</li>\n<li>Not exposing the session ID in the URL also comes under the best practice.</li>\n<li>For every React app, the session ID time-out is a must. Developers can secure progressive web apps by implementing a server-side session manager. It will produce a new session every time the user tries to log in.</li>\n<li>Proper hashing and salting of passwords are mandatory to prevent broken authentication attacks.</li>\n</ul>\n<h2 id=\"xml-external-entities-xxe\" style=\"position:relative;\"><a href=\"#xml-external-entities-xxe\" aria-label=\"xml external entities xxe 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>XML External Entities (XXE)</h2>\n<p>Attackers can perform XML External Entities attacks on React web applications that parse XML input. Here the outdated XML parsers of your React app become vulnerable. Such vulnerability can lead an attacker to perform denial of service, port scanning, server-side request forgery, etc. Such attacks occur when an XML input gets referred to an external entity but has a weakly configured XML parser. Here are some examples where attackers are attempting XEE on React web applications that parse XML input.</p>\n<ul>\n<li>\n<p>The attacker might attempt to extract data from the server.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&lt;?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot;?&gt; &lt;!DOCTYPE sample [</span>\n<span class=\"grvsc-line\">&lt;!ELEMENT sample POO &gt;</span>\n<span class=\"grvsc-line\">&lt;!ENTITY xmlxxe SYSTEM &quot;file:///etc/passwd&quot; &gt;]&gt; &lt;sample&gt; &xmlxxe; &lt;/sample&gt;</span></code></pre>\n</li>\n<li>\n<p>Another code snippet where the attacker explores the private network of the server by tweaking the code:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&lt;!ENTITY xmlxxe SYSTEM &quot;https://186.141.2.1/privnw&quot; &gt;]&gt;</span></code></pre>\n</li>\n<li>\n<p>It is another code snippet where the attacker tries for a Denial of Service (DoS) attack by comprising a potentially perpetual file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&lt;!ENTITY xmlxxe SYSTEM &quot;file:///gkr/rand&quot; &gt;]&gt;</span></code></pre>\n</li>\n</ul>\n<h3 id=\"checklist-to-fix-xxe-vulnerability-in-react-apps\" style=\"position:relative;\"><a href=\"#checklist-to-fix-xxe-vulnerability-in-react-apps\" aria-label=\"checklist to fix xxe vulnerability in react apps 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>Checklist to Fix XXE Vulnerability in React Apps</h3>\n<ul>\n<li>Developers need to keep all the XML libraries and processors fully updated or patched.</li>\n<li>It is a good practice to disable all XML external entities and DTD processing.</li>\n<li>React developers should adopt simpler data formats like JSON instead of XML. It will help avoid the serialization of sensitive data.</li>\n<li>Various Static Application Security Testing (SAST) tools help identify malicious XXE in the code.</li>\n<li>Developers should also perform filtering and server-side input validation to limit injecting unfriendly data input in XML documents or headers. Modern and updated browsers do not allow attackers to run malicious XML scripts as they come with built-in input validation.</li>\n</ul>\n<h2 id=\"zip-slip\" style=\"position:relative;\"><a href=\"#zip-slip\" aria-label=\"zip slip 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>Zip Slip</h2>\n<p>It is another popular React app vulnerability where the malicious actor exploits the app by submitting zip files having malicious or arbitrary code within them. React developers enable adding zip files to decrease the file size while they get uploaded. When the app unzips the archive, its malicious file(s) can overwrite other files or perform arbitrary code execution. Attackers can either harm the files existing in the target system or gain remote access to the system.</p>\n<p>Here is a Zip slip code example demonstrating a ZipEntry path merges to a destination directory without validating that path. Researchers and security professionals have found similar codes in different repositories across many apps.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">Enumeration&lt;ZipEntry&gt; entry = zip.getEntries();</span>\n<span class=\"grvsc-line\"> while (entry.hasMoreElements()) {</span>\n<span class=\"grvsc-line\">ZipEntry ez = entry.nextElement();</span>\n<span class=\"grvsc-line\">File fil = new File(destinationDir, ez.getName());</span>\n<span class=\"grvsc-line\">InputStream input = zip.getInputStream(ez);</span>\n<span class=\"grvsc-line\">IOUtils.copy(input, write(fil));</span>\n<span class=\"grvsc-line\"> }</span></code></pre>\n<p>Here is a <a href=\"https://github.com/snyk/zip-slip-vulnerability\">link</a> to the repository containing libraries and APIs infected by zip slip.</p>\n<h3 id=\"checklist-to-fix-zip-slip-vulnerability-in-react-apps\" style=\"position:relative;\"><a href=\"#checklist-to-fix-zip-slip-vulnerability-in-react-apps\" aria-label=\"checklist to fix zip slip vulnerability in react apps 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>Checklist to Fix Zip Slip Vulnerability in React Apps</h3>\n<ul>\n<li>React developers can search through the project for vulnerable codes. Developers can integrate validation code to the original application's code to check for directory traversal.</li>\n<li>Another way to prevent Zip Slip attacks in React apps is to include the Zip Slip Security Testing solution in the build pipeline of the app.</li>\n<li>Do not allow uploading files having special characters.</li>\n<li>Renaming all the zip files is another best practice to prevent zip slip attacks. Developers should generate new file names for each file before the application leverages them.</li>\n<li>Node.js uses npm libraries as the dependency. React internally uses node.js, and hence any vulnerable library can pose a threat to the React app. It is a good practice to create your own dependencies and libraries rather than using 3rd-party libraries.</li>\n</ul>\n<h2 id=\"cross-site-request-forgery-csrf-or-xsrf\" style=\"position:relative;\"><a href=\"#cross-site-request-forgery-csrf-or-xsrf\" aria-label=\"cross site request forgery csrf or xsrf 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>Cross-site Request Forgery (CSRF or XSRF)</h2>\n<p>CSRF is another React web application vulnerability allowing attackers to persuade users to perform unintentional actions without their direct consent. It does not steal the identity of the legitimate user but acts against their will. For rendering such attacks, the attacker sends an email or a web link convincing the victim to achieve a state-changing request in the application.</p>\n<p>Before going through the checklist on fixing CSRF vulnerabilities, here is a quick example of how the CSRF GET request will be once the attacker tweaks it.\nA standard GET request for a $250 transfer from person1 to person2 might look like this:</p>\n<p>When the attacker induces the user to perform some unintended action or runs a malicious script, the $250 gets transferred to the attacker's account. This malicious request might look something like this:</p>\n<p>Some attackers can also put innocent-looking hyperlinks embedding the request.</p>\n<h3 id=\"checklist-to-fix-react-pwas-from-csrf-vulnerability\" style=\"position:relative;\"><a href=\"#checklist-to-fix-react-pwas-from-csrf-vulnerability\" aria-label=\"checklist to fix react pwas from csrf vulnerability 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>Checklist to Fix React PWAs from CSRF Vulnerability</h3>\n<ul>\n<li>The progressive React web app should not deliver CSRF tokens using Cookies.</li>\n<li>An alternate defense mechanism against CSRF is to leverage a double submit cookie technique.</li>\n<li>Another robust way of preventing an application from a CSRF attack is to add a relevant CSRF token tied to user sessions and strictly validate every case before executing any appropriate action.</li>\n<li>It is always a good choice to shift from HTTP/1.1 to HTTP/2 or HTTP/3. HTTP/2 and 3 are fast, more secure than HTTP/1.1, and almost all modern browsers support them.</li>\n</ul>\n<h2 id=\"vulnerability-in-packages-and-dependencies\" style=\"position:relative;\"><a href=\"#vulnerability-in-packages-and-dependencies\" aria-label=\"vulnerability in packages and 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>Vulnerability in Packages and Dependencies</h2>\n<p>It might happen that you have pushed a React app's code to GitHub. Now an email/notification is popping up saying, \"One of your dependencies has a security vulnerability.\" That is another method where attackers seek the help of malicious packages to gain access to your React applications. Such malicious packages collect valuable app details and user information and send it to a third party. </p>\n<p>These packages can also execute malicious code during the package installation phase. These attackers use the concept of typosquatting to make their attacks seamless. Typosquatting is a method of naming the packages based on their original counterparts. It outwits the developers into downloading these malicious packages that can wreak havoc on the React app.</p>\n<h3 id=\"checklist-to-fix-malicious-package-vulnerability-in-react-apps\" style=\"position:relative;\"><a href=\"#checklist-to-fix-malicious-package-vulnerability-in-react-apps\" aria-label=\"checklist to fix malicious package vulnerability in react apps 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>Checklist to Fix Malicious Package Vulnerability in React Apps</h3>\n<ul>\n<li>One way to detect and remove this vulnerability is to recognize the vulnerable package and find an alternative React package. It is a good practice to analyze your app against malicious package vulnerability.</li>\n<li>Developers can also use SAST tools to detect exploitable code in a React application. SAST tools can scan and inspect all the application's source code, byte code, dependencies, packages, and binaries to uncover security vulnerabilities.</li>\n<li>Since Node uses npm libraries and dependencies and React uses Node, developers should make a checklist of vulnerable libraries like <a href=\"https://github.com/ZJONSSON/node-unzipper\">unzipper</a>, <a href=\"https://github.com/cthackers/adm-zip\">adm-zip</a>, and <a href=\"https://snyk.io/vuln/npm:npm\">other vulnerability release lists</a> for better precaution while developing React applications. </li>\n</ul>\n<h2 id=\"wrapping-up\" style=\"position:relative;\"><a href=\"#wrapping-up\" aria-label=\"wrapping up 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>Wrapping Up</h2>\n<p>Hope this comprehension has given a crisp idea of the top React vulnerabilities and the different checklists developers can use to fix those security flaws. Developers should know how crucial application security is for both the business and its users. As the React features are increasing, there is an equal delay in the number of days taken by the React community to fix any React security issues. </p>\n<p>In this article, we discussed the most well-known vulnerabilities like SQLi, XSS, Broken Authentication, XXE, Zip Slip, CSRF, and Package &#x26; dependency vulnerabilities, plus how to prevent React apps from such attacks. So, developers and product managers should cautiously handle all security-related aspects of a React project by following the checklist given in this article.</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":"December 24, 2021","updated_date":null,"description":"React security vulnerabilities are hard to detect. However, this article talks about the top 7 vulnerabilities and how to fix them to enjoy all the benefits React caters to in developing Progressive Web Applications.","title":"React Security Vulnerabilities and How to Fix/Prevent Them","tags":["React","Vulnerability"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.2820512820512822,"src":"/static/7d6e838c39ee3573adb83d3237a82ee6/ee604/react-security.png","srcSet":"/static/7d6e838c39ee3573adb83d3237a82ee6/69585/react-security.png 200w,\n/static/7d6e838c39ee3573adb83d3237a82ee6/497c6/react-security.png 400w,\n/static/7d6e838c39ee3573adb83d3237a82ee6/ee604/react-security.png 800w,\n/static/7d6e838c39ee3573adb83d3237a82ee6/f3583/react-security.png 1200w,\n/static/7d6e838c39ee3573adb83d3237a82ee6/5707d/react-security.png 1600w,\n/static/7d6e838c39ee3573adb83d3237a82ee6/b6c0e/react-security.png 1926w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Gaurav Kumar Roy","github":"GauravRoy6","avatar":null}}}},{"node":{"excerpt":"Security has become a fundamental aspect to consider while developing an application. As people become more aware and hackers more notorious…","fields":{"slug":"/engineering/guest-post/securing-php-api-with-jwt/"},"html":"<p>Security has become a fundamental aspect to consider while developing an application. As people become more aware and hackers more notorious, you need to employ systems that strengthen your application's data security.</p>\n<p>Previously, it was common to use session storage to secure applications. In recent times, sessions have proved inefficient, which pushed to migrate to authentication with APIs. Even though this was a superb and robust way to secure web applications, it became obsolete as hackers tried to figure out how to crack this authentication.</p>\n<p>As the web evolves to accept more and more users, the research for secure authentication techniques speeds up. In 2010, the world was introduced to a new and secure authentication standard -- JWT. Let's know more about JWT.</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>JSON Web Token (JWT) is a safe way to authenticate users on a web app. Using JWT, you can securely transfer encrypted data and information between a client computer and a server.</p>\n<blockquote>\n<p>Learn more about the <a href=\"https://www.loginradius.com/blog/engineering/guest-post/jwt-vs-sessions/\">differences between sessions and JWTs here</a>.</p>\n</blockquote>\n<p>JWT offers many benefits. Here are some of them.</p>\n<h2 id=\"benefits-of-using-jwt\" style=\"position:relative;\"><a href=\"#benefits-of-using-jwt\" aria-label=\"benefits of using 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>Benefits of Using JWT</h2>\n<ul>\n<li>Compatible with OAuth 2, meaning your applications will be easy to work with the latest security standards.</li>\n<li>JWTs can expire after some time so that no one has uninterrupted access to the website. This is important to protect a website from attacks.</li>\n<li>JSON is used to transmit data, so you can work with any language of your choice and handle the JSON data.</li>\n<li>JWTs are feature-rich and encompass complete information about any authorization request with different aspects.</li>\n</ul>\n<p>Now that you've learned about the advantages, it's time to go deeper into the JWT.</p>\n<h2 id=\"the-structure-of-jwt\" style=\"position:relative;\"><a href=\"#the-structure-of-jwt\" aria-label=\"the structure of 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>The Structure of JWT</h2>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"json\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">eyJ</span><span class=\"mtk7\">0</span><span class=\"mtk1\">eXAiOiJKV</span><span class=\"mtk7\">1</span><span class=\"mtk1\">QiLCJhbGciOiJIUzI</span><span class=\"mtk7\">1</span><span class=\"mtk1\">NiJ</span><span class=\"mtk7\">9</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  .eyJpc</span><span class=\"mtk7\">3</span><span class=\"mtk1\">MiOiJodHRwczpcL</span><span class=\"mtk7\">1</span><span class=\"mtk1\">wvcWEtYXBpLndlbGx</span><span class=\"mtk7\">2</span><span class=\"mtk1\">aWJlLmNvbVwvYXBpXC</span><span class=\"mtk7\">9</span><span class=\"mtk1\">hdXRoXC</span><span class=\"mtk7\">9</span><span class=\"mtk1\">sb</span><span class=\"mtk7\">2</span><span class=\"mtk1\">dpbiIsImlhdCI</span><span class=\"mtk7\">6</span><span class=\"mtk1\">MTYzMDQ</span><span class=\"mtk7\">3</span><span class=\"mtk1\">OTA</span><span class=\"mtk7\">5</span><span class=\"mtk1\">NSwiZXhwIjoxNjMwNDgyNjk</span><span class=\"mtk7\">1</span><span class=\"mtk1\">LCJuYmYiOjE</span><span class=\"mtk7\">2</span><span class=\"mtk1\">MzA</span><span class=\"mtk7\">0</span><span class=\"mtk1\">NzkwOTUsImp</span><span class=\"mtk7\">0</span><span class=\"mtk1\">aSI</span><span class=\"mtk7\">6</span><span class=\"mtk1\">Imtsa</span><span class=\"mtk7\">3</span><span class=\"mtk1\">hHUGpMOVlNTzRSdUsiLCJzdWIiOjc</span><span class=\"mtk7\">3</span><span class=\"mtk1\">ODE</span><span class=\"mtk7\">4</span><span class=\"mtk1\">LCJwcnYiOiIyM</span><span class=\"mtk7\">2</span><span class=\"mtk1\">JkNWM</span><span class=\"mtk7\">4</span><span class=\"mtk1\">OTQ</span><span class=\"mtk7\">5</span><span class=\"mtk1\">ZjYwMGFkYjM</span><span class=\"mtk7\">5</span><span class=\"mtk1\">ZTcwMWM</span><span class=\"mtk7\">0</span><span class=\"mtk1\">MDA</span><span class=\"mtk7\">4</span><span class=\"mtk1\">NzJkYjdhNTk</span><span class=\"mtk7\">3</span><span class=\"mtk1\">NmY</span><span class=\"mtk7\">3</span><span class=\"mtk1\">IiwidXNlcnNfaWQiOjc</span><span class=\"mtk7\">3</span><span class=\"mtk1\">ODE</span><span class=\"mtk7\">4</span><span class=\"mtk1\">LCJtZW</span><span class=\"mtk7\">1</span><span class=\"mtk1\">iZXJzX</span><span class=\"mtk7\">2</span><span class=\"mtk1\">lkIjo</span><span class=\"mtk7\">3</span><span class=\"mtk1\">Nzg</span><span class=\"mtk7\">4</span><span class=\"mtk1\">MzMsInByb</span><span class=\"mtk7\">3</span><span class=\"mtk1\">h</span><span class=\"mtk7\">5</span><span class=\"mtk1\">X</span><span class=\"mtk7\">3</span><span class=\"mtk1\">VzZXJfbWVtYmVyc</span><span class=\"mtk7\">19</span><span class=\"mtk1\">pZCI</span><span class=\"mtk7\">6</span><span class=\"mtk1\">bnVsbH</span><span class=\"mtk7\">0</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  .TxXwLLu</span><span class=\"mtk7\">1</span><span class=\"mtk1\">zWBe</span><span class=\"mtk7\">7</span><span class=\"mtk1\">cLLYdFYy</span><span class=\"mtk7\">3</span><span class=\"mtk1\">P</span><span class=\"mtk7\">2</span><span class=\"mtk1\">HX</span><span class=\"mtk7\">4</span><span class=\"mtk1\">AaLgc</span><span class=\"mtk7\">7</span><span class=\"mtk1\">WfSRtTgeiI</span></span></code></pre>\n<p>The above string is an example of a JWT authentication string. At first glance, it may appear to be a randomly produced string. But don't underestimate; this string is made up of three separate components that are essential in a JWT.</p>\n<h3 id=\"jwt-header\" style=\"position:relative;\"><a href=\"#jwt-header\" aria-label=\"jwt header 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 Header</h3>\n<p>The header of a JWT is the initial section of the string before the first dot. This header is produced by acquiring plain text and performing cryptographic operations on it. Moreover, the header uses a very efficient Base64 encoding procedure.</p>\n<p>You can quickly obtain the JWT's headers using symmetric or asymmetric encryption techniques.</p>\n<h3 id=\"jwt-payload\" style=\"position:relative;\"><a href=\"#jwt-payload\" aria-label=\"jwt payload 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 Payload</h3>\n<p>The string's central component is the JWT's payload part. This string includes all of the important information about a received request and the user or client computer who created the request. There are predefined key-value pair fields in the payload that can be used to offer extra information about the received request. Here is an explanation of common payload fields.</p>\n<ul>\n<li><strong>Sub</strong> - The sub field contains the subject of a JWT payload. It contains unique information about the user and client device that has created this authentication request.</li>\n<li><strong>Iss</strong> - This field contains data about the server that has issued the token. Iss is short for Issuer, which refers to the server.</li>\n<li><strong>Exp</strong> - Unlike other authentication techniques, JWT has an expiration time. This field's name is a short form for the expiration date. It contains data about when the token was issued and the expiration date and time of the issued token.</li>\n</ul>\n<h3 id=\"jwt-signature\" style=\"position:relative;\"><a href=\"#jwt-signature\" aria-label=\"jwt signature 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 Signature</h3>\n<p>A cryptographic operation is performed on the JWT data to obtain this signature. It takes in the payload, secret key, and header value of a JWT. The signature is then generated by applying a function to these obtained values.</p>\n<p>The server and user can verify this signature to know about the data's security and integrity. If this signature matches at both ends, then the data is considered secure, and all other transactions can occur.</p>\n<h2 id=\"using-jwts-to-secure-php-api\" style=\"position:relative;\"><a href=\"#using-jwts-to-secure-php-api\" aria-label=\"using jwts to secure php 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>Using JWTs to Secure PHP API</h2>\n<p>As you've understood everything about JWT, let's secure your PHP API using JWT. Follow the code along, and, in the end, you'll create a tamper-proof PHP API.</p>\n<p>This article creates a simple login page and authenticates it using JWT. This will help you get started with JWT and PHP.</p>\n<p>To follow along, you'll need to have PHP and composer installed on your computer.</p>\n<p>If you haven't already installed composer on your computer, you can <a href=\"https://getcomposer.org/doc/00-intro.md\">learn how to install composer here</a>. Once you've installed composer, run the tool from your project folder. Composer will assist you in installing Firebase PHP-JWT, a third-party library for working with JWTs and Apache.</p>\n<p>Once the library is installed, you'll need to set up a login code in <code>authenticate.php</code>. While you do this, put a code piece that checks and gets the autoloader from the composer tool. The below code helps you achieve this.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;?php</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">declare</span><span class=\"mtk1\">(strict_types=</span><span class=\"mtk7\">1</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">use</span><span class=\"mtk1\"> Firebase\\JWT\\</span><span class=\"mtk10\">JWT</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">require_once</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;../vendor/autoload.php&#39;</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>When the form gets submitted, you need to check the entered data with a data source or database. For our purpose, let's create a <code>hasValidCredentials</code> variable and set it to true. Setting this variable to true means that the data is checked and valid.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;?php</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// extract credentials from the request</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">$hasValidCredentials</span><span class=\"mtk1\">) {</span></span></code></pre>\n<p>Any further coding will be wrapped in this block itself. The value of the <code>hasValidCredentials</code> variable governs all code related to the production and validation of the required JWT. If its value is true, the JWT shall be created; otherwise, an error will be shown.</p>\n<h3 id=\"creating-jwt\" style=\"position:relative;\"><a href=\"#creating-jwt\" aria-label=\"creating 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>Creating JWT</h3>\n<p>Let's start creating the JWT. First, you need to generate some more variables to aid in this process. As you saw in the payload section, you must create:</p>\n<ul>\n<li>a variable that will hold the secret key, which may be retrieved from the environment files;</li>\n<li>another variable to hold information about when the JWT was created;</li>\n<li>a variable that will hold the JWT's expiration date and time;</li>\n<li>a username field to identify the client making the authorization request; and,</li>\n<li>a server name variable to register the server name.</li>\n</ul>\n<p>JWT's can be easily inspected and checked at client-side browsers. So it is better to hide your secret key and other important information in some environment file, which the user cannot access through client-side requests.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">$secret_Key</span><span class=\"mtk1\">  = </span><span class=\"mtk8\">&#39;68V0zWFrS72GbpPreidkQFLfj4v9m3Ti+DXc8OB0gcM=&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$date</span><span class=\"mtk1\">   = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">DateTimeImmutable</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$expire_at</span><span class=\"mtk1\">     = </span><span class=\"mtk12\">$date</span><span class=\"mtk1\">-&gt;</span><span class=\"mtk11\">modify</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;+6 minutes&#39;</span><span class=\"mtk1\">)-&gt;</span><span class=\"mtk11\">getTimestamp</span><span class=\"mtk1\">();      </span><span class=\"mtk3\">// Add 60 seconds</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$domainName</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;your.domain.name&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$username</span><span class=\"mtk1\">   = </span><span class=\"mtk8\">&quot;username&quot;</span><span class=\"mtk1\">;                                           </span><span class=\"mtk3\">// Retrieved from filtered POST data</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$request_data</span><span class=\"mtk1\"> = [</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;iat&#39;</span><span class=\"mtk1\">  =&gt; </span><span class=\"mtk12\">$date</span><span class=\"mtk1\">-&gt;</span><span class=\"mtk11\">getTimestamp</span><span class=\"mtk1\">(),         </span><span class=\"mtk3\">// Issued at: time when the token was generated</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;iss&#39;</span><span class=\"mtk1\">  =&gt; </span><span class=\"mtk12\">$domainName</span><span class=\"mtk1\">,                       </span><span class=\"mtk3\">// Issuer</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;nbf&#39;</span><span class=\"mtk1\">  =&gt; </span><span class=\"mtk12\">$date</span><span class=\"mtk1\">-&gt;</span><span class=\"mtk11\">getTimestamp</span><span class=\"mtk1\">(),         </span><span class=\"mtk3\">// Not before</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;exp&#39;</span><span class=\"mtk1\">  =&gt; </span><span class=\"mtk12\">$expire_at</span><span class=\"mtk1\">,                           </span><span class=\"mtk3\">// Expire</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;userName&#39;</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk12\">$username</span><span class=\"mtk1\">,                     </span><span class=\"mtk3\">// User name</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">];</span></span></code></pre>\n<p>Now you have all the required data in hand; you can easily create a JWT. Here, you'll use the PHP-JWT package's <code>encode()</code> method. This method helps transform your data array into a JSON object.</p>\n<p>Following the conversion to a JSON object, the encode function produces JWT headers and signs the received payload with a cryptographic combination of all the information and the given secret key.</p>\n<p>It is essential to supply three arguments to the <code>encode()</code> method to utilize it correctly. The first argument should be the payload information, which is the data array in this instance. Secondly, you must supply the secret key as an argument; and finally, you must define the cryptographic technique that the function should use to sign the JWT.</p>\n<p>To obtain and return the JWT, you'll have to use the echo method above the encode method, as shown below.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;?php</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">// Encode the array to a JWT string.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">echo</span><span class=\"mtk1\"> </span><span class=\"mtk10\">JWT</span><span class=\"mtk1\">::</span><span class=\"mtk11\">encode</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">$request_data</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">$secret_Key</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&#39;HS512&#39;</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>Now that you have obtained the JWT token, you can transfer it to the client-side and save it using any web programming language of your choice. Let's start with a short JS demonstration of the route ahead.</p>\n<p>First, when a successful form submission takes place, save the created and received JWT in client-side memory. To display some output about the JWT's success, remove the login form and merely display a button that retrieves and displays the JWT's timestamp to the user when it is clicked.</p>\n<p>Here is some sample code for the process mentioned above.</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=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">storeJWT</span><span class=\"mtk1\"> = {}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">loginBtn</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;#frmLogin&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">btnResource</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;#btnGetResource&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">formData</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk12\">forms</span><span class=\"mtk1\">[</span><span class=\"mtk7\">0</span><span class=\"mtk1\">]</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// Inserts the jwt to the store object</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">storeJWT</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setJWT</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">data</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=\"mtk12\">JWT</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">data</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=\"mtk12\">loginBtn</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addEventListener</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;submit&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk12\">e</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\">e</span><span class=\"mtk1\">.</span><span class=\"mtk11\">preventDefault</span><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\">response</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;/authenticate.php&quot;</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\">&quot;POST&quot;</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk8\">&quot;Content-type&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;application/x-www-form-urlencoded; charset=UTF-8&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\">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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">formData</span><span class=\"mtk1\">.</span><span class=\"mtk12\">inputEmail</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\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">formData</span><span class=\"mtk1\">.</span><span class=\"mtk12\">inputPassword</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>\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\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> &gt;= </span><span class=\"mtk7\">200</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> &lt;= </span><span class=\"mtk7\">299</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\">jwt</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk11\">text</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">storeJWT</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setJWT</span><span class=\"mtk1\">(</span><span class=\"mtk12\">jwt</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">frmLogin</span><span class=\"mtk1\">.</span><span class=\"mtk12\">style</span><span class=\"mtk1\">.</span><span class=\"mtk12\">display</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;none&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">btnResource</span><span class=\"mtk1\">.</span><span class=\"mtk12\">style</span><span class=\"mtk1\">.</span><span class=\"mtk12\">display</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;block&quot;</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\">// Handle errors</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=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\">, </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">statusText</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've already produced and submitted the JWT to the user. So now it's time to put the JWT to use on the user side.</p>\n<h3 id=\"using-jwt\" style=\"position:relative;\"><a href=\"#using-jwt\" aria-label=\"using 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>Using JWT</h3>\n<p>As previously stated, if the form submission is successful, you'll display a button to obtain a timestamp. This button will invoke the GET method on the <code>resource.php</code> script. The <code>resource.php</code> script will then set the JWT received after successful authentication in the authentication header.</p>\n<p>The following code will help you achieve this feat.</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=\"mtk12\">btnResource</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addEventListener</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;click&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk12\">e</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\">result</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;/resource.php&quot;</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Authorization:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">`Bearer </span><span class=\"mtk4\">${</span><span class=\"mtk12\">storeJWT</span><span class=\"mtk1\">.</span><span class=\"mtk12\">JWT</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=\"mtk1\">  })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">timeStamp</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\">.</span><span class=\"mtk11\">text</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=\"mtk12\">timeStamp</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span></code></pre>\n<p>Once you've written this code, run the program and enter your credentials into the form fields. A GET request will be sent when you click the submit button. Here is a sample GET request to assist you in making the correct identification.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">GET /resource.php HTTP/</span><span class=\"mtk7\">1.1</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">Host: yourhost.com</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">Connection: keep-alive</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">Accept: *</span><span class=\"mtk3\">/*</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">X-Requested-With: XMLHttpRequest</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvcWEtYXBpLndlbGx2aWJlLmNvbVwvYXBpXC9hdXRoXC9sb2dpbiIsImlhdCI6MTYzMDQ3OTA5NSwiZXhwIjoxNjMwNDgyNjk1LCJuYmYiOjE2MzA0NzkwOTUsImp0aSI6Imtsa3hHUGpMOVlNTzRSdUsiLCJzdWIiOjc3ODE4LCJwcnYiOiIyM2JkNWM4OTQ5ZjYwMGFkYjM5ZTcwMWM0MDA4NzJkYjdhNTk3NmY3IiwidXNlcnNfaWQiOjc3ODE4LCJtZW1iZXJzX2lkIjo3Nzg4MzMsInByb3h5X3VzZXJfbWVtYmVyc19pZCI6bnVsbH0.TxXwLLu1zWBe7cLLYdFYy3P2HX4AaLgc7WfSRtTgeiI</span></span></code></pre>\n<h3 id=\"validating-jwt\" style=\"position:relative;\"><a href=\"#validating-jwt\" aria-label=\"validating 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>Validating JWT</h3>\n<p>If you've followed along until here, everything should be working fine. Now, let's begin with validating the JWT.</p>\n<p>To get help with this operation, you've previously added the composer's autoloader function. You'll now use the <code>preg match</code> function to extract the token from the Bearer header. For this extraction, you'll use the <code>preg match</code> function and supply a regular expression.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> (! </span><span class=\"mtk11\">preg_match</span><span class=\"mtk1\">(</span><span class=\"mtk5\">&#39;/Bearer</span><span class=\"mtk6\">\\s</span><span class=\"mtk5\">(</span><span class=\"mtk6\">\\S</span><span class=\"mtk1\">+</span><span class=\"mtk5\">)/&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">$_SERVER</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&#39;HTTP_AUTHORIZATION&#39;</span><span class=\"mtk1\">], </span><span class=\"mtk12\">$matches</span><span class=\"mtk1\">)) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">header</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;HTTP/1.0 400 Bad Request&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">echo</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;Token not found in request&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">exit</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The code above attempts to extract the token from the Bearer header. In this case, error handling is utilized. Thus if the token is not discovered, an HTTP 404 error is displayed to the user.</p>\n<p>To validate the JWT, you must first compare it to the previously created JWT.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">$jwt</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">$matches</span><span class=\"mtk1\">[</span><span class=\"mtk7\">1</span><span class=\"mtk1\">];</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> (! </span><span class=\"mtk12\">$jwt</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">// No token was able to be extracted from the authorization header</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">header</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;HTTP/1.0 400 Bad Request&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">exit</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The extracted JWT is saved at the first index of the matches array. If the matching array is empty, it means no JWT was extracted. If the preceding code runs successfully, it implies that the JWT has been extracted, and you may now proceed.</p>\n<p>Decoding the received data is required for verifying a JWT. Only the secret key may be used to decode the received data. Once you've obtained the secret key, you may use the static decode function of the PHP-JWT module.</p>\n<p>The decode method requires three arguments, which are as follows.</p>\n<ul>\n<li>The JWT itself</li>\n<li>The secret key</li>\n<li>The algorithm to be used to decode the JWT</li>\n</ul>\n<p>If the decode method succeeds, you may proceed to validate the JWT. The code below will assist you in decoding and validating a JWT.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">$secret_Key</span><span class=\"mtk1\">  = </span><span class=\"mtk8\">&#39;68V0zWFrS72GbpPreidkQFLfj4v9m3Ti+DXc8OB0gcM=&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$token</span><span class=\"mtk1\"> = </span><span class=\"mtk10\">JWT</span><span class=\"mtk1\">::</span><span class=\"mtk11\">decode</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$jwt</span><span class=\"mtk1\">, </span><span class=\"mtk12\">$secret_Key</span><span class=\"mtk1\">, [</span><span class=\"mtk8\">&#39;HS512&#39;</span><span class=\"mtk1\">]);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$now</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">DateTimeImmutable</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$serverName</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;your.domain.name&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">$token</span><span class=\"mtk1\">-&gt;</span><span class=\"mtk12\">iss</span><span class=\"mtk1\"> !== </span><span class=\"mtk12\">$serverName</span><span class=\"mtk1\"> ||</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$token</span><span class=\"mtk1\">-&gt;</span><span class=\"mtk12\">nbf</span><span class=\"mtk1\"> &gt; </span><span class=\"mtk12\">$now</span><span class=\"mtk1\">-&gt;</span><span class=\"mtk11\">getTimestamp</span><span class=\"mtk1\">() ||</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$token</span><span class=\"mtk1\">-&gt;</span><span class=\"mtk12\">exp</span><span class=\"mtk1\"> &lt; </span><span class=\"mtk12\">$now</span><span class=\"mtk1\">-&gt;</span><span class=\"mtk11\">getTimestamp</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\">header</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;HTTP/1.1 401 Unauthorized&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">exit</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>This code will provide all the necessary parameters to the decode function and save the method's result. Then, to prevent unauthorized access, error handling is employed. If any of the fields in the JWT are unavailable, an HTTP 401 error indicating unauthorized access will be issued to the user.</p>\n<h2 id=\"loginradius-authentication-for-php-apps\" style=\"position:relative;\"><a href=\"#loginradius-authentication-for-php-apps\" aria-label=\"loginradius authentication for php apps 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>LoginRadius Authentication for PHP Apps</h2>\n<p>Instead of using the process discussed above, you can use <a href=\"https://accounts.loginradius.com/auth.aspx?plan=developer\">LoginRadius Identity Platform</a> to authenticate your PHP APIs quickly. You can start by referring to <a href=\"https://www.loginradius.com/developers/\">LoginRadius PHP documentation</a>.</p>\n<p>In addition, you can use <a href=\"https://www.loginradius.com/developers/\">LoginRadius PHP SDK</a>, which, in turn, simplifies signup and login for your users by eliminating the need for remembering an extra set of credentials for your app.</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've learned about JWT. Then created a PHP web application and secured it with JWT authentication.</p>\n<p>You understood how easy and important it is to secure a web application.</p>\n<p>You can <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/php\">find the complete code used in this tutorial here</a>.</p>\n<p>Don't forget to try this out for your more significant projects.</p>\n<p>Finally, if you face any problems following this tutorial or have questions, please feel free to comment below. We'll respond as soon as we can to clarify your questions.</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 .mtk7 { color: #B5CEA8; }\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 .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk5 { color: #D16969; }\n  .dark-default-dark .mtk6 { color: #D7BA7D; }\n</style>","frontmatter":{"date":"December 24, 2021","updated_date":null,"description":"This tutorial helps you understand why you should secure your PHP API. Then, it helps you learn how to use JWT with Apache to secure your PHP API.","title":"How to Secure a PHP API Using JWT","tags":["PHP","JWT","Authentication"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/0d1302ecbb6ca63f354aabd22a131331/ee604/jwt.png","srcSet":"/static/0d1302ecbb6ca63f354aabd22a131331/69585/jwt.png 200w,\n/static/0d1302ecbb6ca63f354aabd22a131331/497c6/jwt.png 400w,\n/static/0d1302ecbb6ca63f354aabd22a131331/ee604/jwt.png 800w,\n/static/0d1302ecbb6ca63f354aabd22a131331/f3583/jwt.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Harikrishna Kundariya","github":"espark-biz","avatar":null}}}}]},"markdownRemark":{"excerpt":"Google has prepared a roadmap to restrict third-party cookies in Chrome. Since 04 January 2024, Chrome has rolled out third-party cookie…","fields":{"slug":"/engineering/identity-impact-of-google-chrome-thirdparty-cookie-restrictions/"},"html":"<p>Google has prepared a roadmap to restrict third-party cookies in Chrome. Since 04 January 2024, Chrome has rolled out third-party cookie restrictions for 1% of stable clients and 20% of Canary, Dev, and Beta clients.</p>\n<p><strong>What does it mean for user authentication?</strong></p>\n<p>On one hand, Google believes third-party cookies are widely used for cross-site tracking, greatly affecting user privacy. Hence, Google wants to phase out (or restrict) supporting third-party cookies in Chrome by early Q2 2025 (subject to regulatory processes).</p>\n<p>On the other hand, Google introduced Privacy Sandbox to support the use cases (other than cross-site tracking and advertising) previously implemented using third-party cookies.</p>\n<p>In this article, we’ll discuss:</p>\n<ul>\n<li>How is user authentication (identity) affected?</li>\n<li>What is Google offering as part of Privacy Sandbox to support various identity use cases when third-party cookies are phased out?</li>\n</ul>\n<h2 id=\"how-is-user-authentication-affected\" style=\"position:relative;\"><a href=\"#how-is-user-authentication-affected\" aria-label=\"how is user authentication affected 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 is User Authentication Affected?</h2>\n<p>Third-party cookie restrictions affect user authentication in three ways, as follows.</p>\n<h3 id=\"external-identity-providers\" style=\"position:relative;\"><a href=\"#external-identity-providers\" aria-label=\"external identity providers 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>External Identity Providers</h3>\n<p>If your website or app uses an external Identity Provider (IdP) — like LoginRadius, the IdP sets a third-party cookie when the user authenticates on your app.</p>\n<h3 id=\"web-sso\" style=\"position:relative;\"><a href=\"#web-sso\" aria-label=\"web 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>Web SSO</h3>\n<p>If you have multiple apps across domains within your organization and authentication is handled using an IdP (internal or external) with web SSO, you already use third-party cookies to facilitate seamless access for each user using a single set of credentials.</p>\n<p>If you have implemented web SSO with one primary domain and multiple sub-domains of the primary domain, third-party cookie restrictions may not apply. For now, Google doesn’t consider the cookies set by sub-domains as third-party cookies, although this stance may change in the future.</p>\n<p>For example, you have apps at <code>example.com</code>, <code>travel.example.com</code>, <code>stay.example.com</code>, and web SSO is handled by <code>auth.example.com</code>. In this case, third-party cookie restrictions don’t apply.</p>\n<h3 id=\"federated-sso\" style=\"position:relative;\"><a href=\"#federated-sso\" aria-label=\"federated 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>Federated SSO</h3>\n<p>Federated SSO is similar to, albeit different from, web SSO. It can handle multiple IdPs and applications—aka., Service Providers (SPs)—spanning multiple organizations. It can also implement authentication scenarios that are usually implemented through web SSO.</p>\n<p>Usually, authentication is handled on a separate pop-up or page when the user wants to authenticate rather than on the application or website a user visits. </p>\n<p>For example, you already use federated SSO if you facilitate authentication for a set of apps through multiple social identity providers as well as traditional usernames and passwords.</p>\n<blockquote>\n<p><strong>Note</strong>: It is also possible to store tokens locally, not within cookies. In this case, third-party cookie restrictions won’t affect token-based authentication. However, the restrictions still affect authentication where tokens are stored within third-party cookies (a common and secure method).</p>\n</blockquote>\n<h2 id=\"chromes-alternatives-for-third-party-cookies\" style=\"position:relative;\"><a href=\"#chromes-alternatives-for-third-party-cookies\" aria-label=\"chromes alternatives for third party cookies 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>Chrome’s Alternatives for Third-Party Cookies</h2>\n<p>Google has been developing alternative features and capabilities for Chrome to replace third-party cookies as part of its Privacy Sandbox for Web initiative.</p>\n<p>Specific to authentication, Google recommends the following:</p>\n<ol>\n<li>Cookies Having Independent Partitioned State (CHIPS)</li>\n<li>Storage Access API</li>\n<li>Related Website Sets</li>\n<li>Federated Credential Management (FedCM) API</li>\n</ol>\n<h3 id=\"cookies-having-independent-partitioned-state-chips\" style=\"position:relative;\"><a href=\"#cookies-having-independent-partitioned-state-chips\" aria-label=\"cookies having independent partitioned state chips 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>Cookies Having Independent Partitioned State (CHIPS)</h3>\n<p><a href=\"https://developers.google.com/privacy-sandbox/3pcd/chips\">CHIPS</a> are a restricted way of setting third-party cookies on a top-level site without making them accessible on other top-level sites. Thus, they limit cross-site tracking and enable specific cross-site functionalities, such as maps, chat, and payment embeds.</p>\n<p>For example, a user visits <code>a.com</code> with a map embed from <code>map-example.com</code>, which can set a partitioned cookie that is only accessible on a.com. </p>\n<p>If the user visits <code>b.com</code> with a map embed from <code>map-example.com</code>, it cannot access the partitioned cookie set on <code>a.com</code>. It has to create a separate partitioned cookie specific to <code>b.com</code>, thus blocking cross-site tracking yet allowing limited cross-site functionality.</p>\n<p>You should specifically opt for partitioned cookies (CHIPS), which are set with partitioned and secure cookie attributes.</p>\n<p>If you’re using an external identity provider for your application, CHIPS is a good option to supplant third-party cookie restrictions. </p>\n<p>However, CHIPS may not be ideal if you have a web SSO or federated SSO implementation. It creates separate partitioned cookies for each application with a separate domain, which can increase complexity and create compatibility issues.</p>\n<h3 id=\"storage-access-api\" style=\"position:relative;\"><a href=\"#storage-access-api\" aria-label=\"storage access 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>Storage Access API</h3>\n<p>With <a href=\"https://developers.google.com/privacy-sandbox/3pcd/storage-access-api\">Storage Access API</a>, you can access the local storage in a third-party context through iframes, similar to when users visit it as a top-level site in a first-party context. That is, it gives access to unpartitioned cookies and storage.</p>\n<p>Storage Access API requires explicit user approval to grant access, similar to locations, camera, and microphone permissions. If the user denies access, unpartitioned cookies and storage won’t be accessible in a third-party context.</p>\n<p>It is most suitable when loading cross-site resources and interactions, such as:</p>\n<p>Verifying user sessions when allowing interactions on an embedded social post or providing personalization for an embedded video.\nEmbedded documents requiring user verification status to be accessible.</p>\n<p>As it requires explicit user approval, it is advisable to use Storage Access API when you can’t implement an identity use case with the other options.</p>\n<h3 id=\"related-website-sets\" style=\"position:relative;\"><a href=\"#related-website-sets\" aria-label=\"related website sets 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>Related Website Sets</h3>\n<p>With <a href=\"https://developers.google.com/privacy-sandbox/3pcd/related-website-sets\">Related Website Sets</a>, you can declare a <code>primary</code> website and <code>associatedSites</code> for limited purposes to grant third-party cookie access and local storage for a limited number of sites.</p>\n<p>Chrome automatically recognizes related website sets declared, accepted, and maintained in this open-source GitHub repository: <a href=\"https://github.com/GoogleChrome/related-website-sets\">Related Website Sets</a></p>\n<p>It provides access through Storage Access API directly without prompting for user approval, but only after the user interacts with the relevant iframe.</p>\n<p>It is important to declare a limited number of domains in related website sets that are meaningful and used for specific purposes. Google may block or suspend any exploitative use of this feature.</p>\n<p>The top-level site can also request approval for specific cross-site resources and scripts to Storage Access API using <code>resuestStorageAccessFor()</code> API.</p>\n<p>If you’re using an external identity provider for your web application, you can declare the domain of the identity provider in the related set to ensure limited third-party cookies and storage access to the identity provider, thus ensuring seamless user authentication.</p>\n<p>Related Website Sets can also work to supplement third-party cookie restrictions in web SSO and federated SSO if the number of web applications (or domains) is limited.</p>\n<h3 id=\"federated-credential-management-fedcm-api\" style=\"position:relative;\"><a href=\"#federated-credential-management-fedcm-api\" aria-label=\"federated credential management fedcm 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>Federated Credential Management (FedCM) API</h3>\n<p>FedCM API enables federated SSO without third-party cookies.</p>\n<p>With FedCM API, a user follows these steps for authentication:</p>\n<ol>\n<li>The User navigates to a Service Provider (SP) — aka., Relying Party (RP)</li>\n<li>As the user requests to authenticate, the SP requests the browser through FedCM API to initiate authentication.</li>\n<li>The browser displays a list of available identity providers (supported by the RP), such as social IdPs like Google, Apple, LinkedIn, and Facebook, or other OAuth IdPs like LoginRadius.</li>\n<li>Once the user selects an IdP, the browser communicates with the IdP. Upon valid authentication, the IdP generates a secure token.\nThe browser delivers this secure token to the RP to facilitate user authorization.</li>\n</ol>\n<p>You can access a user demo of FedCM here: <a href=\"https://fedcm-rp-demo.glitch.me/\">FedCM</a>. </p>\n<p>For more information about implementing federated SSO with FedCM API, go through the <a href=\"https://developers.google.com/privacy-sandbox/3pcd/fedcm-developer-guide\">FedCM developer guide</a>.</p>\n<h2 id=\"how-is-loginradius-preparing-for-the-third-party-cookie-phase-out\" style=\"position:relative;\"><a href=\"#how-is-loginradius-preparing-for-the-third-party-cookie-phase-out\" aria-label=\"how is loginradius preparing for the third party cookie phase out 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 is LoginRadius Preparing for the Third-party Cookie Phase-out?</h2>\n<p>Firstly, we’re committed to solving our customers' user identity pain points — and preparing for the third-party cookies phase-out is no different.</p>\n<p>We’ll implement the most relevant and widely useful solutions to facilitate a smooth transition for our customers.</p>\n<p>Please subscribe to our blog for more information. We’ll update you on how we help with the third-party cookie phase-out.</p>\n<h2 id=\"in-conclusion\" style=\"position:relative;\"><a href=\"#in-conclusion\" aria-label=\"in 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>In Conclusion</h2>\n<p>The proposed changes to phase out third-party cookies and suggested alternatives are evolving as Google has been actively collaborating and discussing changes with the border community.</p>\n<p>Moreover, browsers like Firefox, Safari, and Edge may approach restricting third-party cookies differently than Google does.</p>\n<p>From LoginRadius, we’ll keep you updated on what we’re doing as a leading Customer Identity and Access Management (CIAM) vendor to prepare for the third-party cookie phase-out.</p>\n<h2 id=\"glossary\" style=\"position:relative;\"><a href=\"#glossary\" aria-label=\"glossary 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>Glossary</h2>\n<p><strong>Top-level site</strong>: It is the primary site a user has visited.</p>\n<p><strong>First-party cookie</strong>: A cookie set by the top-level site.</p>\n<p><strong>Third-party cookie</strong>: A cookie set by a domain other than the top-level site. For example, let’s assume that a user has visited <code>a.com</code>, which might use an embed from <code>loginradius.com</code> to facilitate authentication. If <code>loginradius.com</code> sets a cookie when the user visits <code>a.com</code>, it is called a third-party cookie as the user hasn’t directly visited <code>loginradius.com</code>.</p>\n<h2 id=\"references\" style=\"position:relative;\"><a href=\"#references\" aria-label=\"references 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>References</h2>\n<ul>\n<li><a href=\"https://developers.google.com/privacy-sandbox/3pcd/prepare/prepare-for-phaseout\">Changes to Chrome's treatment of third-party cookies</a></li>\n<li><a href=\"https://developers.google.com/privacy-sandbox/3pcd/guides/identity\">Check the impact of the third-party cookie changes on your sign-in workflows</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</style>","frontmatter":{"date":"July 08, 2024","updated_date":null,"description":"Google Chrome has planned to phase out third-party cookies, which will affect different website functionalities depending on third-party cookies. This blog focuses on how this phase-out affects identity and user authentication and discusses alternatives for overcoming challenges.","title":"How Chrome’s Third-Party Cookie Restrictions Affect User Authentication?","tags":["Identity","Cookies","Chrome"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/eb7396060c0adc430dbed2d04b63d431/ee604/third-party-cookies-phaseout-chrome.png","srcSet":"/static/eb7396060c0adc430dbed2d04b63d431/69585/third-party-cookies-phaseout-chrome.png 200w,\n/static/eb7396060c0adc430dbed2d04b63d431/497c6/third-party-cookies-phaseout-chrome.png 400w,\n/static/eb7396060c0adc430dbed2d04b63d431/ee604/third-party-cookies-phaseout-chrome.png 800w,\n/static/eb7396060c0adc430dbed2d04b63d431/f3583/third-party-cookies-phaseout-chrome.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Raghunath Reddy","github":"raghunath-r-a","avatar":null}}}},"pageContext":{"limit":6,"skip":24,"currentPage":5,"type":"//engineering//","numPages":52,"pinned":"17fa0d7b-34c8-51c4-b047-df5e2bbaeedb"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}