{"componentChunkName":"component---src-templates-blog-list-template-js","path":"/48","result":{"data":{"allMarkdownRemark":{"edges":[{"node":{"excerpt":"Introduction We are thrilled to announce the release of our annual industry report, Consumer Digital Identity Trend Report 2022. We surveyed…","fields":{"slug":"/identity/loginradius-consumer-identity-trend-report-2022/"},"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>We are thrilled to announce the release of our annual industry report, <strong>Consumer Digital Identity Trend Report 2022</strong>.</p>\n<p>We surveyed over 500 brands and 1.17 billion users worldwide from the LoginRadius Identity Platform to provide an in-depth analysis of the consumer data market, including changes in consumer behavior over time and their projected impact on business practices and IT requirements.</p>\n<h2 id=\"evolution-is-essential-for-a-great-consumer-experience\" style=\"position:relative;\"><a href=\"#evolution-is-essential-for-a-great-consumer-experience\" aria-label=\"evolution is essential for a great consumer experience permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Evolution is Essential for a Great Consumer Experience</h2>\n<p>The next few years will be a pivotal time for the digital consumer identity space. One critical aspect covered in this report is that consumers are evolving from the traditional registration model to a more personalized, easy to authenticate model that's secure. Keeping up is a challenge – and it requires businesses to adjust their identity management systems.</p>\n<p>The report findings highlight that if your business wants to stand out in a highly competitive world, you’ll need to make a huge improvement in your interactions with your customers. This means not just your interactions with them but also theirs with your brand, starting from registration to checkout.</p>\n<p>Businesses can achieve this by tailoring authentication and login methods to their customers' preferences, such as passwordless login or multi-factor authentication via email or SMS, or social sign-on.</p>\n<p><a href=\"https://www.loginradius.com/resource/consumer-digital-identity-trend-report-2022\"><img src=\"/751ac241127c4800bbe4a3e228d82798/RP-2022.webp\" alt=\"RP-2022\"></a></p>\n<h2 id=\"key-highlights-of-the-consumer-identity-report-2022\" style=\"position:relative;\"><a href=\"#key-highlights-of-the-consumer-identity-report-2022\" aria-label=\"key highlights of the consumer identity report 2022 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Key Highlights of the Consumer Identity Report 2022</h2>\n<p>As a company strongly focused on CIAM, we analyzed our global customers over the past year, and discovered the following:</p>\n<ul>\n<li>95.06% of companies offer standard login using an email ID.</li>\n<li>59.11% of companies use MFA via SMS messaging and 40.89% via an authenticator app.</li>\n<li>The phone login has the highest return rate of 31.11%. Next is passwordless login with 29.41%. </li>\n</ul>\n<p>Some more findings of the report have been outlined in the infographic below. </p>\n<p><img src=\"/c1f398c0fa9dcdf917e94019591e6bc6/infographic-report-22.webp\" alt=\"infographic-report-22\"></p>\n<p>Overall, the CIAM trend report highlights: </p>\n<ul>\n<li>The preferable login methods by end-users.</li>\n<li>The preferable verification process.</li>\n<li>The performance benchmarks for identity management platforms.</li>\n</ul>\n<h2 id=\"looking-ahead\" style=\"position:relative;\"><a href=\"#looking-ahead\" aria-label=\"looking ahead permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Looking Ahead</h2>\n<p>Companies that treat customer identity management as a strategic business process instead of an operational activity will have the advantage in today’s marketplace. These companies will be able to operate more efficiently through lower customer acquisition, onboarding, and support costs and higher customer retention rates.</p>\n<p>If you are trying to improve your customer experience, the finding of this report will definitely impact your bottom line. </p>\n<p>Download a complimentary copy of the LoginRadius <a href=\"https://www.loginradius.com/resource/consumer-digital-identity-trend-report-2022\">Consumer Identity Trend Report</a> here.</p>\n<p><a href=\"https://www.loginradius.com/contact-us?utm_source=blog&#x26;utm_medium=web&#x26;utm_campaign=loginradius-consumer-identity-trend-report-2022\"><img src=\"/8fce571f703a5970dbb1359a2fe0e51a/book-a-demo-loginradius.webp\" alt=\"book-a-demo-loginradius\"></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</style>","frontmatter":{"date":"April 27, 2022","updated_date":null,"description":"As a company strongly focused on CIAM, LoginRadius analyzed its global customers over the past year and compiled over 40 unique trends in its annual Consumer Identity Trend report 2022.","title":"LoginRadius Releases Consumer Identity Trend Report 2022, Key Login Methods Highlighted","tags":["industry-news","consumer-identity","identity-trends","digital-identity"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5873015873015872,"src":"/static/f4132dee4b3c9f2070be747e6fdf7e33/7f8e9/report-cover.webp","srcSet":"/static/f4132dee4b3c9f2070be747e6fdf7e33/61e93/report-cover.webp 200w,\n/static/f4132dee4b3c9f2070be747e6fdf7e33/1f5c5/report-cover.webp 400w,\n/static/f4132dee4b3c9f2070be747e6fdf7e33/7f8e9/report-cover.webp 768w","sizes":"(max-width: 768px) 100vw, 768px"}}},"author":{"id":"Rakesh Soni","github":"oyesoni","avatar":"rakesh-soni.webp"}}}},{"node":{"excerpt":"When your webapp has a large amount of data to visualize, you don't want your users to wait 10 seconds before seeing something. One…","fields":{"slug":"/engineering/guest-post/http-streaming-with-nodejs-and-fetch-api/"},"html":"<p>When your webapp has a large amount of data to visualize, you don't want your users to wait 10 seconds before seeing something.</p>\n<p>One technique that is often overlooked is HTTP streaming. It's broadly supported, works well, and doesn't require fancy libraries.</p>\n<p>We're going to go through how we can use HTTP streaming in our applications and what to consider when we do so.</p>\n<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>When building web applications, we typically have a REST API with GET endpoints that do something like this:</p>\n<ol>\n<li>Parse the request (URL, query params, etc..)</li>\n<li>Query data from a database</li>\n<li>Convert the database results into JSON</li>\n<li>Send the JSON response back</li>\n</ol>\n<p>The API will typically wait for each step to complete before going on to the next one, and by step 4, the database result and the JSON objects are all in memory before the request is handled, and everything can be cleaned up.</p>\n<p>This works, and there is nothing wrong with it (KISS, right?) as long as your database query results are small and quickly available.</p>\n<p>But let's say you want to render a chart with 10k data points. Querying will not be as smooth anymore.\nThe simple way will work, but ideally, you don't want to accumulate all the data in memory before sending the response.</p>\n<p>With HTTP streaming, you can start rendering the chart even before your query is complete.</p>\n<p>To make it happen:</p>\n<ol>\n<li>Your API should use HTTP streaming to send its response.</li>\n<li>Your webapp should use the <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API\">Fetch API</a> to make the request so that it can process the streaming response.</li>\n</ol>\n<h2 id=\"create-a-streaming-api\" style=\"position:relative;\"><a href=\"#create-a-streaming-api\" aria-label=\"create a streaming 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>Create a Streaming API</h2>\n<p>In this example, we use <a href=\"https://koajs.com/\">Koa</a> for the API, but you can use other libraries like Express or plain Node.js. Most will have support for streaming.</p>\n<p>Let's create an API:</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=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Koa</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;koa&#39;</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=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Koa</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"></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=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">ctx</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\">ctx</span><span class=\"mtk1\">.</span><span class=\"mtk12\">request</span><span class=\"mtk1\">.</span><span class=\"mtk12\">url</span><span class=\"mtk1\"> === </span><span class=\"mtk8\">&#39;/measurements.json&#39;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">ctx</span><span class=\"mtk1\">.</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk11\">set</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;content-type&#39;</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 class=\"mtk3\">// This is where the magic happens: set a stream as the response body</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">ctx</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">fs</span><span class=\"mtk1\">.</span><span class=\"mtk11\">createReadStream</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;./measurements.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>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">http</span><span class=\"mtk1\">.</span><span class=\"mtk11\">createServer</span><span class=\"mtk1\">(</span><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">callback</span><span class=\"mtk1\">()).</span><span class=\"mtk11\">listen</span><span class=\"mtk1\">(</span><span class=\"mtk7\">3000</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>This code creates an API with 1 endpoint <code>GET /measurements</code> that will respond with the contents of a JSON file with 10k measurements.</p>\n<p>The file looks like this:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"json\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">[</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  { </span><span class=\"mtk12\">&quot;id&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;1&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;timestamp&quot;</span><span class=\"mtk1\">:  </span><span class=\"mtk8\">&quot;2022-01-19T10:39:00.000Z&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;value&quot;</span><span class=\"mtk1\">:  </span><span class=\"mtk7\">239.34</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  { </span><span class=\"mtk12\">&quot;id&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;2&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;timestamp&quot;</span><span class=\"mtk1\">:  </span><span class=\"mtk8\">&quot;2022-01-19T10:40:00.000Z&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;value&quot;</span><span class=\"mtk1\">:  </span><span class=\"mtk7\">820.14</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  { </span><span class=\"mtk12\">&quot;id&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;3&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;timestamp&quot;</span><span class=\"mtk1\">:  </span><span class=\"mtk8\">&quot;2022-01-19T10:41:00.000Z&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;value&quot;</span><span class=\"mtk1\">:  </span><span class=\"mtk7\">926.03</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  { </span><span class=\"mtk12\">&quot;id&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;4&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;timestamp&quot;</span><span class=\"mtk1\">:  </span><span class=\"mtk8\">&quot;2022-01-19T10:42:00.000Z&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;value&quot;</span><span class=\"mtk1\">:  </span><span class=\"mtk7\">513.01</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk3\">// ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  { </span><span class=\"mtk12\">&quot;id&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;99998&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;timestamp&quot;</span><span class=\"mtk1\">:  </span><span class=\"mtk8\">&quot;2022-03-29T21:16:00.000Z&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;value&quot;</span><span class=\"mtk1\">:  </span><span class=\"mtk7\">13.81</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  { </span><span class=\"mtk12\">&quot;id&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;99999&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;timestamp&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;2022-03-29T21:17:00.000Z&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;value&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk7\">465.28</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  { </span><span class=\"mtk12\">&quot;id&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;100000&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;timestamp&quot;</span><span class=\"mtk1\">:  </span><span class=\"mtk8\">&quot;2022-03-29T21:18:00.000Z&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;value&quot;</span><span class=\"mtk1\">:  </span><span class=\"mtk7\">71.95</span><span class=\"mtk1\"> }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">]</span></span></code></pre>\n<p>We're creating an HTTP/1.1 server with Node's <code>http</code> module. By setting <code>ctx.body</code> to a stream, data will be sent to the requester as soon as it is loaded using a mechanism called <a href=\"https://en.wikipedia.org/wiki/Chunked_transfer_encoding\">chunked transfer encoding</a>.</p>\n<p>This saves time and memory of your API because it doesn't have to accumulate the whole result in memory before sending the response.</p>\n<p>In a real application, you're probably using a database instead of a pre-created JSON file.\nIf you're using MongoDB, you can create a stream with the <a href=\"https://docs.mongodb.com/drivers/node/current/fundamentals/crud/read-operations/cursor/#stream-api\">cursor's <code>stream()</code> method</a>.</p>\n<h2 id=\"consume-a-streaming-api-from-a-webapp\" style=\"position:relative;\"><a href=\"#consume-a-streaming-api-from-a-webapp\" aria-label=\"consume a streaming api from a webapp permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Consume a Streaming API From a Webapp</h2>\n<p>The <code>GET /measurements</code> endpoint we created can be consumed with any HTTP client, but you have to use the <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams#consuming_a_fetch_as_a_stream\">Fetch API</a> to take advantage of streaming.</p>\n<p><code>fetch()</code> will set <code>response.body</code> to a <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream\">ReadableStream</a> for streaming responses.</p>\n<p>Here's how you can read a streaming response:</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=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;http://localhost:3000/measurements.json&#39;</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=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">response</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\">// response.body is a ReadableStream</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">reader</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getReader</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">for</span><span class=\"mtk1\"> </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> (</span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">chunk</span><span class=\"mtk1\"> </span><span class=\"mtk4\">of</span><span class=\"mtk1\"> </span><span class=\"mtk11\">readChunks</span><span class=\"mtk1\">(</span><span class=\"mtk12\">reader</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\">`received chunk of size </span><span class=\"mtk4\">${</span><span class=\"mtk12\">chunk</span><span class=\"mtk1\">.</span><span class=\"mtk12\">length</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>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// readChunks() reads from the provided reader and yields the results into an async iterable</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">readChunks</span><span class=\"mtk1\">(</span><span class=\"mtk12\">reader</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\">        async* [</span><span class=\"mtk10\">Symbol</span><span class=\"mtk1\">.</span><span class=\"mtk12\">asyncIterator</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\">readResult</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">reader</span><span class=\"mtk1\">.</span><span class=\"mtk11\">read</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">while</span><span class=\"mtk1\"> (!</span><span class=\"mtk12\">readResult</span><span class=\"mtk1\">.</span><span class=\"mtk12\">done</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">yield</span><span class=\"mtk1\"> </span><span class=\"mtk12\">readResult</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\">readResult</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">reader</span><span class=\"mtk1\">.</span><span class=\"mtk11\">read</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>If you run the API that we created and then run the code above in a web browser, you'll see <code>received chunk of size x</code> several times in the console with varying x:</p>\n<p><img src=\"/75cf5afcae41ee6a1ea963da104389ff/console-received-chunk-of-size-x.gif\" alt=\"The console showing &#x22;received chunk of size x&#x22;\"></p>\n<p>To see it more clearly, open up Developer Tools (F12) and set network throttling to 3G. It will take longer for the file to download, so you can see that the chunks are being processed gradually.</p>\n<p>That's all very nice, but the chunks themselves are not very useful. You want to process the measurements that are in these chunks. Ideally, you would have an async iterable that gradually yields the JSON objects as they come in so that you can use <code>for await</code> to iterate over the measurements instead of the chunks.</p>\n<p>JavaScript doesn't have a JSON parser that can deal with streams. Let's assume we have a function that can do this called <code>parseJsonStream(readableStream)</code>. More details and a simple implementation can be found in \"Streaming Considerations\" below.</p>\n<p>We would then be able to do 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=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;http://localhost:3000/measurements.json&#39;</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=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">response</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\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">measurementsReceived</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=\"mtk15\">for</span><span class=\"mtk1\"> </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> (</span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">measurement</span><span class=\"mtk1\"> </span><span class=\"mtk4\">of</span><span class=\"mtk1\"> </span><span class=\"mtk11\">parseJsonStream</span><span class=\"mtk1\">(</span><span class=\"mtk12\">response</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=\"mtk12\">measurementsReceived</span><span class=\"mtk1\">++;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk3\">// To prevent the console from flooding we only show 1 in every 100 measurements</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">measurementsReceived</span><span class=\"mtk1\"> % </span><span class=\"mtk7\">100</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=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">`measurement with id {</span><span class=\"mtk4\">${</span><span class=\"mtk12\">measurement</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk4\">}</span><span class=\"mtk8\">} at time </span><span class=\"mtk4\">${</span><span class=\"mtk12\">measurement</span><span class=\"mtk1\">.</span><span class=\"mtk12\">timestamp</span><span class=\"mtk4\">}</span><span class=\"mtk8\"> has value [</span><span class=\"mtk4\">${</span><span class=\"mtk12\">measurement</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</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></code></pre>\n<p>This is the result:</p>\n<p><img src=\"/e2d673ca68b3af5f9fa335ce755032ed/console-measurements.gif\" alt=\"The console showing &#x22;measurement with id ... has value ...&#x22;\"></p>\n<p>This is a very powerful mechanism. Instead of <code>console.log()</code> statements, imagine a line chart where the measurements gradually become visible as more data comes in.</p>\n<p>This is an example created with <a href=\"https://echarts.apache.org/\">Apache ECharts</a>:</p>\n<p><img src=\"/76f92b76f2a2c36236b5610800abb88c/chart-loading-gradually.gif\" alt=\"A line chart gradually becoming visible as data comes in\"></p>\n<p>Before the Fetch API, it was impossible to do this because the alternative, <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest\"><code>XMLHttpRequest</code></a>, will load the whole response into memory before providing it to your code.</p>\n<p>Modern applications don't use <code>XMLHttpRequest</code> directly, but a lot of libraries like <a href=\"https://axios-http.com/\">Axios</a> or Angular's <a href=\"https://angular.io/api/common/http/HttpClient\">HttpClient</a> rely on it to make requests.</p>\n<p>People would rely on more advanced technologies like <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API\">WebSockets</a> to stream data.</p>\n<h2 id=\"http2-for-streaming\" style=\"position:relative;\"><a href=\"#http2-for-streaming\" aria-label=\"http2 for streaming permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>HTTP/2 for Streaming</h2>\n<p>You might have heard that HTTP/2 has a more efficient mechanism for streaming, and you would be right. So let's see if we can use HTTP/2.</p>\n<p>From the side of your webapp, the browser will automatically determine if it can communicate with the server over HTTP/2 and use it if it's available. The Fetch API will do this transparently, so you do not need to make any changes to your webapp.</p>\n<p>What you need to do is make your API available over HTTP/2:</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=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Koa</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;koa&#39;</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=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Koa</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"></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=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">ctx</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\">ctx</span><span class=\"mtk1\">.</span><span class=\"mtk12\">request</span><span class=\"mtk1\">.</span><span class=\"mtk12\">url</span><span class=\"mtk1\"> === </span><span class=\"mtk8\">&#39;/measurements.json&#39;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">ctx</span><span class=\"mtk1\">.</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk11\">set</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;content-type&#39;</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 class=\"mtk12\">ctx</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">fs</span><span class=\"mtk1\">.</span><span class=\"mtk11\">createReadStream</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;./measurements.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>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">http2</span><span class=\"mtk1\">.</span><span class=\"mtk11\">createSecureServer</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\">key:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">fs</span><span class=\"mtk1\">.</span><span class=\"mtk11\">readFileSync</span><span class=\"mtk1\">(</span><span class=\"mtk12\">path</span><span class=\"mtk1\">.</span><span class=\"mtk11\">resolve</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;path/to/localhost-key.pem&#39;</span><span class=\"mtk1\">)),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">cert:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">fs</span><span class=\"mtk1\">.</span><span class=\"mtk11\">readFileSync</span><span class=\"mtk1\">(</span><span class=\"mtk12\">path</span><span class=\"mtk1\">.</span><span class=\"mtk11\">resolve</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;path/to/localhost.pem&#39;</span><span class=\"mtk1\">)),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">callback</span><span class=\"mtk1\">(),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">).</span><span class=\"mtk11\">listen</span><span class=\"mtk1\">(</span><span class=\"mtk7\">3000</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>This code is mostly the same as for HTTP/1.1 with two notable differences:</p>\n<ul>\n<li>We're using Node's <code>http2</code> module instead of <code>http</code>.</li>\n<li>We're using <code>HTTPS</code> instead of plain <code>HTTP</code> because this is mandatory for HTTP/2. You can set up HTTPS and get the <code>cert</code> and <code>key</code> files using <a href=\"https://github.com/FiloSottile/mkcert\">mkcert</a>. Or, use one of the other mechanisms described in this article: <a href=\"https://web.dev/how-to-use-local-https/\">Use HTTPS for Local Development</a></li>\n</ul>\n<p>That's it!</p>\n<p>If you restart the API and check the network tab in Developer Tools, you'll see that your application will now stream over HTTP/2 (don't forget to update the URL in your webapp, start with <code>https://</code> instead of <code>http://</code>).</p>\n<h2 id=\"http-streaming-considerations\" style=\"position:relative;\"><a href=\"#http-streaming-considerations\" aria-label=\"http streaming considerations permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>HTTP Streaming Considerations</h2>\n<p>In the code above, we assumed that there was a function <code>parseJsonStream(readableStream)</code> that would parse a <code>ReadableStream</code> containing JSON into an async iterable of objects.</p>\n<p>The difficulty is that reading from a <code>ReadableStream</code> will give you chunks of data that don't necessarily correspond to anything meaningful. To illustrate, let's take a look at this example:</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=\"mtk1\">[</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  { </span><span class=\"mtk12\">&quot;id&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;1&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;timestamp&quot;</span><span class=\"mtk1\">:  </span><span class=\"mtk8\">&quot;2022-01-19T10:39:00.000Z&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;value&quot;</span><span class=\"mtk1\">:  </span><span class=\"mtk7\">239.34</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  { </span><span class=\"mtk12\">&quot;id&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;2&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;timestamp&quot;</span><span class=\"mtk1\">:  </span><span class=\"mtk8\">&quot;2022-01-19T10:40:00.000Z&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;value&quot;</span><span class=\"mtk1\">:  </span><span class=\"mtk7\">820.14</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  { </span><span class=\"mtk12\">&quot;id&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;3&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;timestamp&quot;</span><span class=\"mtk1\">:  </span><span class=\"mtk8\">&quot;2022-01-19T10:41:00.000Z&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;value&quot;</span><span class=\"mtk1\">:  </span><span class=\"mtk7\">926.03</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  { </span><span class=\"mtk12\">&quot;id&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;4&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;timestamp&quot;</span><span class=\"mtk1\">:  </span><span class=\"mtk8\">&quot;2022-01-19T10:42:00.000Z&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">&quot;value&quot;</span><span class=\"mtk1\">:  </span><span class=\"mtk7\">513.01</span><span class=\"mtk1\"> }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">]</span></span></code></pre>\n<p>We could receive this JSON in chunks like this:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">[</span>\n<span class=\"grvsc-line\">  { &quot;id&quot;: &quot;1&quot;, &quot;timestamp&quot;:  &quot;2022-01-19T10:39:00.000Z&quot;, &quot;value&quot;:  239.34 },</span>\n<span class=\"grvsc-line\">  { &quot;id&quot;: &quot;2&quot;, &quot;tim</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"> estamp&quot;:  &quot;2022-01-19T10:40:00.000Z&quot;, &quot;value&quot;:  820.14 },</span>\n<span class=\"grvsc-line\">  { &quot;id&quot;: &quot;3&quot;, &quot;timestamp&quot;:  &quot;2022-01-19T10:41:00.000Z&quot;, &quot;value&quot;:  926.03 },</span>\n<span class=\"grvsc-line\">  { &quot;id&quot;: &quot;4&quot;, &quot;timestamp&quot;:  &quot;2022-01-19T10:42</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">:00.000Z&quot;, &quot;value&quot;:  513.01 }</span>\n<span class=\"grvsc-line\">]</span></code></pre>\n<p>You need some way to determine where one measurement object starts and ends. To simplify this, we created a JSON file where each line contains precisely one object. Parsing the stream becomes manageable when we can make this assumption.</p>\n<p>Here is the implementation of <code>parseJsonStream(readableStream)</code></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=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk4\">*</span><span class=\"mtk11\">parseJsonStream</span><span class=\"mtk1\">(</span><span class=\"mtk12\">readableStream</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">for</span><span class=\"mtk1\"> </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> (</span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">line</span><span class=\"mtk1\"> </span><span class=\"mtk4\">of</span><span class=\"mtk1\"> </span><span class=\"mtk11\">readLines</span><span class=\"mtk1\">(</span><span class=\"mtk12\">readableStream</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getReader</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\">trimmedLine</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">line</span><span class=\"mtk1\">.</span><span class=\"mtk11\">trim</span><span class=\"mtk1\">().</span><span class=\"mtk11\">replace</span><span class=\"mtk1\">(</span><span class=\"mtk5\">/,</span><span class=\"mtk11\">$</span><span class=\"mtk5\">/</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;&#39;</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\">trimmedLine</span><span class=\"mtk1\"> !== </span><span class=\"mtk8\">&#39;[&#39;</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">trimmedLine</span><span class=\"mtk1\"> !== </span><span class=\"mtk8\">&#39;]&#39;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">yield</span><span class=\"mtk1\"> </span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">parse</span><span class=\"mtk1\">(</span><span class=\"mtk12\">trimmedLine</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk4\">*</span><span class=\"mtk11\">readLines</span><span class=\"mtk1\">(</span><span class=\"mtk12\">reader</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\">textDecoder</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">TextDecoder</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\">partOfLine</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">for</span><span class=\"mtk1\"> </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> (</span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">chunk</span><span class=\"mtk1\"> </span><span class=\"mtk4\">of</span><span class=\"mtk1\"> </span><span class=\"mtk11\">readChunks</span><span class=\"mtk1\">(</span><span class=\"mtk12\">reader</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\">chunkText</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">textDecoder</span><span class=\"mtk1\">.</span><span class=\"mtk11\">decode</span><span class=\"mtk1\">(</span><span class=\"mtk12\">chunk</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\">chunkLines</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">chunkText</span><span class=\"mtk1\">.</span><span class=\"mtk11\">split</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;</span><span class=\"mtk6\">\\n</span><span class=\"mtk8\">&#39;</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\">chunkLines</span><span class=\"mtk1\">.</span><span class=\"mtk12\">length</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\">partOfLine</span><span class=\"mtk1\"> += </span><span class=\"mtk12\">chunkLines</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=\"mtk15\">else</span><span class=\"mtk1\"> </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">chunkLines</span><span class=\"mtk1\">.</span><span class=\"mtk12\">length</span><span class=\"mtk1\"> &gt; </span><span class=\"mtk7\">1</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">yield</span><span class=\"mtk1\"> </span><span class=\"mtk12\">partOfLine</span><span class=\"mtk1\"> + </span><span class=\"mtk12\">chunkLines</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=\"mtk15\">for</span><span class=\"mtk1\"> (</span><span class=\"mtk4\">let</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\">i</span><span class=\"mtk1\"> &lt; </span><span class=\"mtk12\">chunkLines</span><span class=\"mtk1\">.</span><span class=\"mtk12\">length</span><span class=\"mtk1\"> - </span><span class=\"mtk7\">1</span><span class=\"mtk1\">; </span><span class=\"mtk12\">i</span><span class=\"mtk1\">++) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">yield</span><span class=\"mtk1\"> </span><span class=\"mtk12\">chunkLines</span><span class=\"mtk1\">[</span><span class=\"mtk12\">i</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\">partOfLine</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">chunkLines</span><span class=\"mtk1\">[</span><span class=\"mtk12\">chunkLines</span><span class=\"mtk1\">.</span><span class=\"mtk12\">length</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</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\">readChunks</span><span class=\"mtk1\">(</span><span class=\"mtk12\">reader</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\">        async* [</span><span class=\"mtk10\">Symbol</span><span class=\"mtk1\">.</span><span class=\"mtk12\">asyncIterator</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\">readResult</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">reader</span><span class=\"mtk1\">.</span><span class=\"mtk11\">read</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">while</span><span class=\"mtk1\"> (!</span><span class=\"mtk12\">readResult</span><span class=\"mtk1\">.</span><span class=\"mtk12\">done</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">yield</span><span class=\"mtk1\"> </span><span class=\"mtk12\">readResult</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\">readResult</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">reader</span><span class=\"mtk1\">.</span><span class=\"mtk11\">read</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>If you have control over the API you're calling, you can use the \"1 object per line\" formatting as part of the contract, but know that it could be prone to breaking. For robust JSON support, we need a real streaming parser.</p>\n<p>Other options include using a format with one object per line by default, like CSV, or a more advanced format with built-in support for streaming like <a href=\"https://arrow.apache.org/docs/js/\">Apache Arrow</a>.</p>\n<h2 id=\"advantages\" style=\"position:relative;\"><a href=\"#advantages\" aria-label=\"advantages permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Advantages</h2>\n<ol>\n<li><strong>Snappy User Experience:</strong> You can start showing data as soon as it's available.</li>\n<li><strong>Scalable API:</strong> No memory usage spikes from accumulating results in memory.</li>\n<li>Uses plain HTTP and a standard JavaScript API. There are no connections to manage or complicated frameworks that might become obsolete in a few years.</li>\n</ol>\n<h2 id=\"disadvantages\" style=\"position:relative;\"><a href=\"#disadvantages\" aria-label=\"disadvantages permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Disadvantages</h2>\n<ol>\n<li>Implementation is slightly more involved than using regular API calls.</li>\n<li>\n<p>Error handling becomes more difficult because HTTP status code 200 will be sent as soon as streaming starts. What do we do when something goes wrong in the middle of the stream?</p>\n<p>When something goes wrong, your API should close the stream. Your webapp can then determine if the stream was complete and show a fitting message to the user if it's not. For example: when using a JSON response, as we discussed, you can check that the last line contains only \"]\".</p>\n</li>\n<li>No streaming JSON parser is currently available. Needs formatting assumptions as part of the contract or a more unconventional format.</li>\n</ol>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>You have learned how to stream HTTP data efficiently using Node.js and HTTP without congesting or burdening the memory. You have also understood the advantages and disadvantages of HTTP streaming.</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 .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk5 { color: #D16969; }\n  .dark-default-dark .mtk6 { color: #D7BA7D; }\n</style>","frontmatter":{"date":"April 27, 2022","updated_date":null,"description":"Do you know that you can stream HTTP data for efficient visualization? Learn more about how you can stream data with HTTP using Node.js and Fetch API.","title":"Implement HTTP Streaming with Node.js and Fetch API","tags":["Node.js","Fetch API","Streaming"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/e38eeb01b3a5ba1c6afe8f7ebbb43a6b/58556/http-streaming-with-nodejs-and-fetch-api.webp","srcSet":"/static/e38eeb01b3a5ba1c6afe8f7ebbb43a6b/61e93/http-streaming-with-nodejs-and-fetch-api.webp 200w,\n/static/e38eeb01b3a5ba1c6afe8f7ebbb43a6b/1f5c5/http-streaming-with-nodejs-and-fetch-api.webp 400w,\n/static/e38eeb01b3a5ba1c6afe8f7ebbb43a6b/58556/http-streaming-with-nodejs-and-fetch-api.webp 800w,\n/static/e38eeb01b3a5ba1c6afe8f7ebbb43a6b/99238/http-streaming-with-nodejs-and-fetch-api.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Nick Van Nieuwenhuyse","github":"Nivani","avatar":null}}}},{"node":{"excerpt":"Introduction It is an indisputable reality that authentication is critical in any application or system if you want to secure user data and…","fields":{"slug":"/engineering/guest-post/session-authentication-with-nestjs-and-mongodb/"},"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>It is an indisputable reality that authentication is critical in any application or system if you want to secure user data and enable secure access to information. Authentication is the procedure of establishing or demonstrating that something is true, legitimate, or valid.</p>\n<h2 id=\"prerequisites\" style=\"position:relative;\"><a href=\"#prerequisites\" aria-label=\"prerequisites permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Prerequisites</h2>\n<p>This tutorial is a hands-on demonstration. To follow along, ensure you have the following in place:</p>\n<ul>\n<li><a href=\"https://nodejs.org/en/\">Node.js</a> running in your system because NestJS is a Node.js framework</li>\n<li><a href=\"https://www.mongodb.com/\">MongoDB</a> installed</li>\n</ul>\n<h2 id=\"what-is-nestjs\" style=\"position:relative;\"><a href=\"#what-is-nestjs\" aria-label=\"what is nestjs permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 NestJS?</h2>\n<p>Nest (NestJS) is a Node.js server-side application framework for building scalable, efficient applications.</p>\n<p>It is written in TypeScript and built on Express, a very minimalistic framework that is great on its own but lacks structure. It combines programming paradigms such as object-oriented programming, functional programming, and functional reactive programming.</p>\n<p>It is a framework to use if you want a lot of structure on your backend. Its syntax and structure are very similar to AngularJS, a front-end framework. And it uses TypeScript, services, and dependency injection in the same way that AngularJS does.</p>\n<p>It employs modules and controllers, and you can build controllers for a file using the command-line interface.</p>\n<p>NestJS modules allow you to group related controllers and service providers into a single code file. Simply put, a NestJS module is a TypeScript file with the <strong>@Module</strong> annotation (). This decorator informs the NestJS framework about which controllers, service providers, and other associated resources will be instantiated and used by the app code later.</p>\n<h2 id=\"what-is-session-based-authentication\" style=\"position:relative;\"><a href=\"#what-is-session-based-authentication\" aria-label=\"what is session based authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is Session-based Authentication?</h2>\n<p>Session-based authentication is a method of user authentication in which the server creates a session after a successful log-in, with the session ID stored in a cookie or local storage in your browser.</p>\n<p>Upon subsequent requests, your cookie is validated against the session ID stored on the server. If there is a match, the request is considered valid and processed.</p>\n<p>When using this authentication method, it is critical to keep the following security best practices in mind:</p>\n<ul>\n<li>Generate long and random session IDs (128 bits is the recommended length) to make brute force attacks ineffective</li>\n<li>Avoid storing any sensitive or user-specific data</li>\n<li>Make HTTPS communications mandatory for all session-based apps</li>\n<li>Create cookies that have secure and HTTP-only attributes</li>\n</ul>\n<h2 id=\"why-session-based-authentication\" style=\"position:relative;\"><a href=\"#why-session-based-authentication\" aria-label=\"why session based authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Why Session-based Authentication?</h2>\n<p>Session-based authentication is more secure than most authentication methods because it is simple, secure, and has a limited storage size. It is also thought to be the best option for websites in the same root domain.</p>\n<h2 id=\"project-setup\" style=\"position:relative;\"><a href=\"#project-setup\" aria-label=\"project setup permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Project Setup</h2>\n<p>Start your project setup by installing Nest CLI globally. You don’t need to do this if you already have NestJS CLI installed.</p>\n<p>The Nest CLI is a command-line interface tool for setting up, developing, and maintaining Nest applications.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">npm i -g @nestjs/cli</span></span></code></pre>\n<p>Now, let’s set up your project by running the following command:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">nest new session-based-auth</span></code></pre>\n<p>The above command creates a Nest application with some boilerplates, then prompts you to choose your preferred package manager to install the required modules to run your application. For demonstration, this tutorial uses <strong>npm</strong>. Hit the enter key to continue with <strong>npm</strong>.</p>\n<p><img src=\"/9382e66fea36e23b091b84e01a760db0/hDnzpIVA.webp\" alt=\"Choose your preferred package manager\"></p>\n<p>If everything went well, you should see an output like the one on the screenshot below on your terminal.</p>\n<p><img src=\"/389af814b354994ea99495e669ae501b/Hv_Nxk_A.webp\" alt=\"Screenshot - Thanks for installing NEST\"></p>\n<p>Once the installation is complete, move into your project directory, and run the application with the command below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm run start:dev</span></code></pre>\n<p>The above command runs the application and watches for changes. Your project <code>src</code> folder structure should look as follows.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">└───src</span>\n<span class=\"grvsc-line\">│   └───app.controller.ts</span>\n<span class=\"grvsc-line\">│   └───app.modules.ts</span>\n<span class=\"grvsc-line\">│   └───app.service.ts</span>\n<span class=\"grvsc-line\">│   └───main.ts</span></code></pre>\n<h2 id=\"install-dependencies\" style=\"position:relative;\"><a href=\"#install-dependencies\" aria-label=\"install dependencies permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Install Dependencies</h2>\n<p>Now that your application is set up, let's install the dependencies needed.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm install --save @nestjs/passport passport passport-local</span></code></pre>\n<p>The above command installs <a href=\"https://www.passportjs.org/\">Passport.js</a>, a popular nest.js authentication library.</p>\n<p>Also, install the types for the strategy with the command below:</p>\n<p>It contains type definitions for <code>passport-local</code>.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm install --save-dev @types/passport-local</span></code></pre>\n<h2 id=\"set-up-mongodb-database-in-nestjs\" style=\"position:relative;\"><a href=\"#set-up-mongodb-database-in-nestjs\" aria-label=\"set up mongodb database in nestjs permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 MongoDB Database in NestJS</h2>\n<p>To set up and connect your database, install the Mongoose package and the NestJS wrapper with the following command:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm install --save @nestjs/mongoose mongoose</span></code></pre>\n<p>The Mongoose NestJS wrapper helps you use Mongoose in the NestJS application and gives approved TypeScript support.</p>\n<p>Now, head over to your <code>app.module.ts</code>, and import the <code>mongoose</code> module from <code>@nestjs/mongoose</code>. Then call the <code>forRoot()</code> method, a method provided by the Mongoose module, and pass in your database URL string.</p>\n<p>Setting up your database connection in <code>app.module.ts</code> helps your application connect to the database immediately as the server starts — after running your application since it’s the first module to be loaded.</p>\n<p><code>app.module.ts</code></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=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Module</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/common&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">MongooseModule</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/mongoose&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">AppController</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./app.controller&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">AppService</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./app.service&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">@</span><span class=\"mtk11\">Module</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">imports:</span><span class=\"mtk1\"> [</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">MongooseModule</span><span class=\"mtk1\">.</span><span class=\"mtk11\">forRoot</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk8\">&quot;mongodb+srv://&lt;username&gt;:&lt;password&gt;@cluster0.kngtf.mongodb.net/session-auth?retryWrites=true&w=majority&quot;</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\">controllers:</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">AppController</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">providers:</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">AppService</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">AppModule</span><span class=\"mtk1\"> {}</span></span></code></pre>\n<h2 id=\"create-users-module\" style=\"position:relative;\"><a href=\"#create-users-module\" aria-label=\"create users module permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Users Module</h2>\n<p>For separation concerns, to make your code clean and well organized, create a module specifically for users using the NestJS CLI by running the following command:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">nest g module users</span></code></pre>\n<p>The above command creates a <code>users</code> folder with <code>users.module.ts</code> and updates <code>app.module.ts</code></p>\n<p>Also, create <code>users.service.ts</code> and <code>users.controller.ts</code> files with the following commands:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">nest g service users</span>\n<span class=\"grvsc-line\">nest g controller users</span></code></pre>\n<p>Note that you can create your folders and files manually without using the nest CLI, but using the CLI automatically updates the necessary folders and makes your life easier.</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>The next step is to create your UserSchema, but first, add a <code>users.model.ts</code> file, where you will create <code>UserSchema</code></p>\n<p>This should be the shape of our application <code>src</code> folder now.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">└───src</span>\n<span class=\"grvsc-line\">│   └───users</span>\n<span class=\"grvsc-line\">│   │   └───users.controller.ts</span>\n<span class=\"grvsc-line\">│   │   └───users.model.ts</span>\n<span class=\"grvsc-line\">│   │   └───users.module.ts</span>\n<span class=\"grvsc-line\">│   │   └───users.service.ts</span>\n<span class=\"grvsc-line\">│   └───app.controller.ts</span>\n<span class=\"grvsc-line\">│   └───app.module.ts</span>\n<span class=\"grvsc-line\">│   └───app.service.ts</span>\n<span class=\"grvsc-line\">│   └───main.ts</span></code></pre>\n<p>To create <code>UserSchema</code>, import everything as mongoose from the mongoose package in <code>users.model.ts</code>. Then call the new mongoose schema, a blueprint of the user Model, and pass in a JavaScript object where you will define the user object and data.</p>\n<p><code>users.model.ts</code></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=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk4\">*</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> </span><span class=\"mtk12\">mongoose</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;mongoose&quot;</span></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=\"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>\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\">required:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">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>\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\">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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  { </span><span class=\"mtk12\">timestamps:</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>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">interface</span><span class=\"mtk1\"> </span><span class=\"mtk10\">User</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">mongoose</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Document</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=\"mtk10\">string</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=\"mtk10\">string</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=\"mtk10\">string</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Also, create an interface for your Model that extends mongoose, a document that helps you populate your MongoDB collections.</p>\n<p>Head over to your <code>users.module.ts</code> and import <code>MongooseModule</code> in the imports array. Then call the <code>forFeature()</code> method provided by <code>MongooseModule</code>, and pass in an array of object that takes in name and schema.</p>\n<p>This will enable you to share the file anywhere with the help of dependency injection.</p>\n<p><code>users.module.ts</code></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=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Module</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/common&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">MongooseModule</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/mongoose&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UsersController</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./users.controller&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UserSchema</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./users.model&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UsersService</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./users.service&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">@</span><span class=\"mtk11\">Module</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">imports:</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">MongooseModule</span><span class=\"mtk1\">.</span><span class=\"mtk11\">forFeature</span><span class=\"mtk1\">([{ </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;user&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">schema:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">UserSchema</span><span class=\"mtk1\"> }])],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">controllers:</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">UsersController</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">providers:</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">UsersService</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">UsersModule</span><span class=\"mtk1\"> {}</span></span></code></pre>\n<p>In <code>users.module.ts</code>, export the <code>UsersService</code> to enable you to access it in another module.</p>\n<p><code>users.module.ts</code></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=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Module</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/common&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">MongooseModule</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/mongoose&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UsersController</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./users.controller&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UserSchema</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./users.model&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UsersService</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./users.service&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">@</span><span class=\"mtk11\">Module</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">imports:</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">MongooseModule</span><span class=\"mtk1\">.</span><span class=\"mtk11\">forFeature</span><span class=\"mtk1\">([{ </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;user&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">schema:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">UserSchema</span><span class=\"mtk1\"> }])],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">controllers:</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">UsersController</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">providers:</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">UsersService</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">exports:</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">UsersService</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">UsersModule</span><span class=\"mtk1\"> {}</span></span></code></pre>\n<p>It's usually a good idea to encapsulate the business logic in a separate class. Such a class is known as a service. The job of this class is to process the controller's requests and perform the business logic.</p>\n<p>In <code>users.service.ts</code> file, import <code>Model</code> from <code>mongoose</code>, <code>User</code> from <code>users.model.ts</code>, and <code>InjectModel</code> from <code>@nestjs/mongoose</code>. Then add a method to the <code>UsersService</code> class that takes a username and password, and call the method <code>insertUser()</code>.</p>\n<p><code>users.service.ts</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=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Injectable</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@nestjs/common&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">InjectModel</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@nestjs/mongoose&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Model</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;mongoose&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">User</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./users.model&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">@</span><span class=\"mtk11\">Injectable</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">UsersService</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(@</span><span class=\"mtk11\">InjectModel</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;user&#39;</span><span class=\"mtk1\">) </span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk4\">readonly</span><span class=\"mtk1\"> </span><span class=\"mtk12\">userModel</span><span class=\"mtk1\">: </span><span class=\"mtk10\">Model</span><span class=\"mtk1\">&lt;</span><span class=\"mtk10\">User</span><span class=\"mtk1\">&gt;) {}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">insertUser</span><span class=\"mtk1\">(</span><span class=\"mtk12\">userName</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</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=\"mtk11\">toLowerCase</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\">newUser</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">this</span><span class=\"mtk1\">.</span><span class=\"mtk10\">userModel</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">newUser</span><span class=\"mtk1\">.</span><span class=\"mtk11\">save</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\">newUser</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>Now that the <code>UsersService</code> class is ready, you need to inject it into your controller. But first, let's talk about storing the users' passwords securely.</p>\n<p>The most critical aspect of the registration procedure is the users’ passwords, which must not be saved in plain text. It is the responsibility of the user to create a strong password, but it is your obligation as a developer to keep their passwords secure. If a database breach occurs, the users' passwords would be exposed. And what happens if it’s stored in plain text? I believe you know the answer. To address this, hash the passwords using bcrypt.</p>\n<p>So, install <code>bcrypt</code> and <code>@types/bcrypt</code> with the following command:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"15\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm install @types/bcrypt bcrypt</span></code></pre>\n<p>With that out of the way, set up your controller. First, import your <code>UsersService</code> class and everything from <code>bcrypt</code>. Then add a constructor and a method that allows you to add a user; it will handle incoming post requests, call it <code>addUser</code>, with a function body where you'll hash the password.</p>\n<p><code>users.controller.ts</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=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Body</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Controller</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Post</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@nestjs/common&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UsersService</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./users.service&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk4\">*</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;bcrypt&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">@</span><span class=\"mtk11\">Controller</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;users&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">UsersController</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk4\">readonly</span><span class=\"mtk1\"> </span><span class=\"mtk12\">usersService</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UsersService</span><span class=\"mtk1\">) {}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk3\">//post / signup</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  @</span><span class=\"mtk11\">Post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/signup&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">addUser</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    @</span><span class=\"mtk11\">Body</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;password&#39;</span><span class=\"mtk1\">) </span><span class=\"mtk12\">userPassword</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=\"mtk11\">Body</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;username&#39;</span><span class=\"mtk1\">) </span><span class=\"mtk12\">userName</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">saltOrRounds</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">10</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\">hashedPassword</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><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\">userPassword</span><span class=\"mtk1\">, </span><span class=\"mtk12\">saltOrRounds</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">usersService</span><span class=\"mtk1\">.</span><span class=\"mtk11\">insertUser</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\">hashedPassword</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\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">msg:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;User successfully registered&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">userId:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</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\">userName:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</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 registration happens in the <code>app.module.ts</code> file, which is achieved by adding the <code>UsersModule</code> to the <code>@Module()</code> decorator's imports' array in <code>app.module.ts</code>.</p>\n<p><code>app.module.ts</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=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Module</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/common&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">MongooseModule</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/mongoose&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">AppController</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./app.controller&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">AppService</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./app.service&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UsersModule</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./users/users.module&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">@</span><span class=\"mtk11\">Module</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">imports:</span><span class=\"mtk1\"> [</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">MongooseModule</span><span class=\"mtk1\">.</span><span class=\"mtk11\">forRoot</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk8\">&quot;mongodb+srv://&lt;username&gt;:&lt;password&gt;@cluster0.kngtf.mongodb.net/session-auth?retryWrites=true&w=majority&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">UsersModule</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\">controllers:</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">AppController</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">providers:</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">AppService</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">AppModule</span><span class=\"mtk1\"> {}</span></span></code></pre>\n<p>Congratulations! You are done with the registration. You can now register a user with a username and password.</p>\n<p>Now, with registration out of the way, add a <code>getUser</code> function to your <code>UsersService</code> with the <code>findOne</code> method to find a user by username.</p>\n<p><code>users.service.ts</code></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=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Injectable</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@nestjs/common&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">InjectModel</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@nestjs/mongoose&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Model</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;mongoose&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">User</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./users.model&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">@</span><span class=\"mtk11\">Injectable</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">UsersService</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(@</span><span class=\"mtk11\">InjectModel</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;user&#39;</span><span class=\"mtk1\">) </span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk4\">readonly</span><span class=\"mtk1\"> </span><span class=\"mtk12\">userModel</span><span class=\"mtk1\">: </span><span class=\"mtk10\">Model</span><span class=\"mtk1\">&lt;</span><span class=\"mtk10\">User</span><span class=\"mtk1\">&gt;) {}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">insertUser</span><span class=\"mtk1\">(</span><span class=\"mtk12\">userName</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</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=\"mtk11\">toLowerCase</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\">newUser</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">this</span><span class=\"mtk1\">.</span><span class=\"mtk10\">userModel</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">newUser</span><span class=\"mtk1\">.</span><span class=\"mtk11\">save</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\">newUser</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">getUser</span><span class=\"mtk1\">(</span><span class=\"mtk12\">userName</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=\"mtk4\">const</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=\"mtk11\">toLowerCase</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=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">userModel</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\">return</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></code></pre>\n<h2 id=\"create-authentication-module\" style=\"position:relative;\"><a href=\"#create-authentication-module\" aria-label=\"create authentication module permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Authentication Module</h2>\n<p>Just as for users, create an auth module and service specifically for all the authentications/verifications. To do that, run the following commands:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"19\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">nest g module auth</span>\n<span class=\"grvsc-line\">nest g service auth</span></code></pre>\n<p>The above will create an auth folder, <code>auth.module.ts</code>, and <code>auth.service.ts</code>, and update the <code>auth.module.ts</code> and <code>app.module.ts</code> files.</p>\n<p>At this point, the shape of your application <code>src</code> folder should look as follows.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"20\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">└───src</span>\n<span class=\"grvsc-line\">│   └───auth</span>\n<span class=\"grvsc-line\">│   │   └───auth.module.ts</span>\n<span class=\"grvsc-line\">│   │   └───auth.service.ts</span>\n<span class=\"grvsc-line\">│   └───users</span>\n<span class=\"grvsc-line\">│   │   └───users.controller.ts</span>\n<span class=\"grvsc-line\">│   │   └───users.model.ts</span>\n<span class=\"grvsc-line\">│   │   └───users.module.ts</span>\n<span class=\"grvsc-line\">│   │   └───users.service.ts</span>\n<span class=\"grvsc-line\">│   └───app.controller.ts</span>\n<span class=\"grvsc-line\">│   └───app.module.ts</span>\n<span class=\"grvsc-line\">│   └───app.service.ts</span>\n<span class=\"grvsc-line\">│   └───main.ts</span></code></pre>\n<p>The above generate command will update your <code>app.module.ts</code>, and it will look like the code snippet below:</p>\n<p><code>app.module.ts</code></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=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Module</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/common&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">MongooseModule</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/mongoose&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">AppController</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./app.controller&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">AppService</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./app.service&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UsersModule</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./users/users.module&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">AuthModule</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./auth/auth.module&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">@</span><span class=\"mtk11\">Module</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">imports:</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">UsersModule</span><span class=\"mtk1\">, </span><span class=\"mtk12\">AuthModule</span><span class=\"mtk1\">, </span><span class=\"mtk12\">MongooseModule</span><span class=\"mtk1\">.</span><span class=\"mtk11\">forRoot</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">//database url string</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;mongodb://localhost:27017/myapp&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">controllers:</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">AppController</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">providers:</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">AppService</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">AppModule</span><span class=\"mtk1\"> {}</span></span></code></pre>\n<h2 id=\"authenticate-users\" style=\"position:relative;\"><a href=\"#authenticate-users\" aria-label=\"authenticate 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>Authenticate Users</h2>\n<p>Go to your <code>auth.module.ts</code> file and add <code>UsersModule</code> in the imports array to enable access to the <code>UsersService</code> exported from the <code>users.module.ts</code> file.</p>\n<p><code>auth.module.ts</code></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=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Module</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/common&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UsersModule</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;src/users/users.module&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>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">@</span><span class=\"mtk11\">Module</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">imports:</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">UsersModule</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">providers:</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">AuthService</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">AuthModule</span><span class=\"mtk1\"> {}</span></span></code></pre>\n<p>In your <code>auth.service.ts</code> file, call the constructor so you can inject the <code>UsersService</code>, and add a method for validation that will take a username and password.</p>\n<p>To add some basic validations, check if the user exists in the database, and compare the given password with the one in your database to ensure it matches. If it exists, return the user in the <code>request.user</code> object — else, return null.</p>\n<p><code>auth.service.ts</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=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Injectable</span><span class=\"mtk1\">, </span><span class=\"mtk12\">NotAcceptableException</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@nestjs/common&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UsersService</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;src/users/users.service&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk4\">*</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;bcrypt&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    @</span><span class=\"mtk11\">Injectable</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">AuthService</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk4\">readonly</span><span class=\"mtk1\"> </span><span class=\"mtk12\">usersService</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UsersService</span><span class=\"mtk1\">) {}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">validateUser</span><span class=\"mtk1\">(</span><span class=\"mtk12\">username</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">): </span><span class=\"mtk10\">Promise</span><span class=\"mtk1\">&lt;</span><span class=\"mtk10\">any</span><span class=\"mtk1\">&gt; {</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=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">usersService</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getUser</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=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">passwordValid</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><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>\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=\"mtk15\">throw</span><span class=\"mtk1\"> </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">NotAcceptableException</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;could not find the user&#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=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">user</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">passwordValid</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=\"mtk12\">userId:</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 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>\n<span class=\"grvsc-line\"><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 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>Going further, create a new file and name it <code>local.strategy.ts</code>. This file will represent the strategy from <code>Passport.js</code>, which you installed earlier, that is the <code>local strategy</code>. And within it, pass in the strategy, which is the <code>Strategy</code> from <code>passport-local</code>.</p>\n<p>Create a constructor and inject the <code>AuthService</code>, call the <code>super()</code> method; ensure to call the <code>super()</code> method.</p>\n<p><code>local.strategy.ts</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=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Injectable</span><span class=\"mtk1\">, </span><span class=\"mtk12\">UnauthorizedException</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@nestjs/common&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">PassportStrategy</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@nestjs/passport&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Strategy</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;passport-local&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">AuthService</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./auth.service&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    @</span><span class=\"mtk11\">Injectable</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">LocalStrategy</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk11\">PassportStrategy</span><span class=\"mtk1\">(</span><span class=\"mtk12\">Strategy</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk4\">readonly</span><span class=\"mtk1\"> </span><span class=\"mtk12\">authService</span><span class=\"mtk1\">: </span><span class=\"mtk10\">AuthService</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">super</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">validate</span><span class=\"mtk1\">(</span><span class=\"mtk12\">username</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">): </span><span class=\"mtk10\">Promise</span><span class=\"mtk1\">&lt;</span><span class=\"mtk10\">any</span><span class=\"mtk1\">&gt; {</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\">username</span><span class=\"mtk1\">.</span><span class=\"mtk11\">toLowerCase</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=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">authService</span><span class=\"mtk1\">.</span><span class=\"mtk11\">validateUser</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=\"mtk15\">throw</span><span class=\"mtk1\"> </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">UnauthorizedException</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\">return</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></code></pre>\n<p>Go back to your <code>auth.module.ts</code> file. Then add <code>PassportModule</code> to imports and <code>LocalStrategy</code> to providers.</p>\n<p><code>auth.module.ts</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=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Module</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/common&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">PassportModule</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/passport&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UsersModule</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;src/users/users.module&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>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">LocalStrategy</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./local.strategy&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">@</span><span class=\"mtk11\">Module</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">imports:</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">UsersModule</span><span class=\"mtk1\">, </span><span class=\"mtk12\">PassportModule</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">providers:</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">AuthService</span><span class=\"mtk1\">, </span><span class=\"mtk12\">LocalStrategy</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">AuthModule</span><span class=\"mtk1\"> {}</span></span></code></pre>\n<p>Now, add the login route to your <code>users.controller.ts</code>:</p>\n<p><code>users.controller.ts</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"26\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Body</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Controller</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Post</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Request</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@nestjs/common&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk4\">*</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;bcrypt&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UsersService</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./users.service&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    @</span><span class=\"mtk11\">Controller</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;users&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">UsersController</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk4\">readonly</span><span class=\"mtk1\"> </span><span class=\"mtk12\">usersService</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UsersService</span><span class=\"mtk1\">) {}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk3\">//post / signup</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">Post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/signup&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">addUser</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        @</span><span class=\"mtk11\">Body</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;password&#39;</span><span class=\"mtk1\">) </span><span class=\"mtk12\">userPassword</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=\"mtk11\">Body</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;username&#39;</span><span class=\"mtk1\">) </span><span class=\"mtk12\">userName</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      ) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">saltOrRounds</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">10</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\">hashedPassword</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><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\">userPassword</span><span class=\"mtk1\">, </span><span class=\"mtk12\">saltOrRounds</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">usersService</span><span class=\"mtk1\">.</span><span class=\"mtk11\">insertUser</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\">hashedPassword</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\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">msg:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;User successfully registered&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">userId:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</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\">userName:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</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=\"mtk3\">//Post / Login</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">Post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/login&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">login</span><span class=\"mtk1\">(@</span><span class=\"mtk11\">Request</span><span class=\"mtk1\">() </span><span class=\"mtk12\">req</span><span class=\"mtk1\">): </span><span class=\"mtk10\">any</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\">User:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">req</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\">msg:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;User logged in&#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></code></pre>\n<p>Now that you have all these put in place, you still cannot log in a user because there is nothing to trigger the login route. Here, use <a href=\"https://docs.nestjs.com/guards\">Guards</a> to achieve that.</p>\n<p>Create a file and name it <code>local.auth.guard.ts</code>, then a class <code>LocalAuthGuard</code> that extends <code>AuthGuard</code> from <code>NestJS/passport</code>, where you will provide the name of the strategy and pass in the name of your strategy, <code>local</code>.</p>\n<p><code>local.auth.guard.ts.</code></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=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Injectable</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/common&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">AuthGuard</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/passport&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">@</span><span class=\"mtk11\">Injectable</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">LocalAuthGuard</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk11\">AuthGuard</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;local&quot;</span><span class=\"mtk1\">) {}</span></span></code></pre>\n<p>Add the <code>UseGuard</code> decorator to your login route in the <code>users.controller.ts</code> file, and pass in the <code>LocalAuthGuard</code>.</p>\n<p><code>users.controller.ts</code></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=\"mtk1\">    </span><span class=\"mtk15\">import</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Controller</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Post</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">UseGuards</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Request</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@nestjs/common&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk4\">*</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;bcrypt&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">LocalAuthGuard</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;src/auth/local.auth.guard&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UsersService</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./users.service&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    @</span><span class=\"mtk11\">Controller</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;users&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">UsersController</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk4\">readonly</span><span class=\"mtk1\"> </span><span class=\"mtk12\">usersService</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UsersService</span><span class=\"mtk1\">) {}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk3\">//post / signup</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">Post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/signup&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">addUser</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        @</span><span class=\"mtk11\">Body</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;password&#39;</span><span class=\"mtk1\">) </span><span class=\"mtk12\">userPassword</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=\"mtk11\">Body</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;username&#39;</span><span class=\"mtk1\">) </span><span class=\"mtk12\">userName</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      ) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">saltOrRounds</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">10</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\">hashedPassword</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><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\">userPassword</span><span class=\"mtk1\">, </span><span class=\"mtk12\">saltOrRounds</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">usersService</span><span class=\"mtk1\">.</span><span class=\"mtk11\">insertUser</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\">hashedPassword</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\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">msg:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;User successfully registered&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">userId:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</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\">userName:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</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=\"mtk3\">//Post / Login</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">UseGuards</span><span class=\"mtk1\">(</span><span class=\"mtk12\">LocalAuthGuard</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">Post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/login&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">login</span><span class=\"mtk1\">(@</span><span class=\"mtk11\">Request</span><span class=\"mtk1\">() </span><span class=\"mtk12\">req</span><span class=\"mtk1\">): </span><span class=\"mtk10\">any</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\">User:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">req</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\">msg:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;User logged in&#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></code></pre>\n<p>Finally, you can log in a user with a registered username and password.</p>\n<h2 id=\"protect-authentication-routes\" style=\"position:relative;\"><a href=\"#protect-authentication-routes\" aria-label=\"protect authentication 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 Authentication Routes</h2>\n<p>You have successfully set up user authentication. Now, protect your routes from unauthorized access by limiting access to just authenticated users. Go to your <code>users.controller.ts</code> file, and add another route — name it ‘protected’ and make it return the <code>req.user</code> object.</p>\n<p><code>users.controller.ts</code></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=\"mtk1\">    </span><span class=\"mtk15\">import</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Controller</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Get</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Post</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">UseGuards</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Request</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@nestjs/common&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk4\">*</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;bcrypt&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">LocalAuthGuard</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;src/auth/local.auth.guard&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UsersService</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./users.service&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    @</span><span class=\"mtk11\">Controller</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;users&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">UsersController</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk4\">readonly</span><span class=\"mtk1\"> </span><span class=\"mtk12\">usersService</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UsersService</span><span class=\"mtk1\">) {}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk3\">//signup</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">Post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/signup&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">addUser</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        @</span><span class=\"mtk11\">Body</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;password&#39;</span><span class=\"mtk1\">) </span><span class=\"mtk12\">userPassword</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=\"mtk11\">Body</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;username&#39;</span><span class=\"mtk1\">) </span><span class=\"mtk12\">userName</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      ) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">saltOrRounds</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">10</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\">hashedPassword</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><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\">userPassword</span><span class=\"mtk1\">, </span><span class=\"mtk12\">saltOrRounds</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">usersService</span><span class=\"mtk1\">.</span><span class=\"mtk11\">insertUser</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\">hashedPassword</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\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">msg:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;User successfully registered&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">userId:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</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\">userName:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</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=\"mtk3\">//Post / Login</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">UseGuards</span><span class=\"mtk1\">(</span><span class=\"mtk12\">LocalAuthGuard</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">Post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/login&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">login</span><span class=\"mtk1\">(@</span><span class=\"mtk11\">Request</span><span class=\"mtk1\">() </span><span class=\"mtk12\">req</span><span class=\"mtk1\">): </span><span class=\"mtk10\">any</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\">User:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">req</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\">msg:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;User logged in&#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=\"mtk3\">// Get / protected</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">Get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/protected&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">getHello</span><span class=\"mtk1\">(@</span><span class=\"mtk11\">Request</span><span class=\"mtk1\">() </span><span class=\"mtk12\">req</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=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">req</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></code></pre>\n<p>The protected route in the above code will return an empty object instead of returning the user’s details when a logged-in user makes a request to it because it already lost the login.</p>\n<p>To get that sorted, this is where the session-based authentication comes in.</p>\n<p>In session-based authentication, when a user logs in, the user is saved in a session so that any subsequent request by the user after login will grab the details from the session and grant the user easy access. The session expires when the user logs out.</p>\n<p>To start session-based auth, install <a href=\"https://docs.nestjs.com/techniques/session\">express-session</a> and the NestJS types using the following command:</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=\"mtk12\">npm</span><span class=\"mtk1\"> </span><span class=\"mtk12\">install</span><span class=\"mtk1\"> </span><span class=\"mtk12\">express</span><span class=\"mtk1\">-</span><span class=\"mtk12\">session</span><span class=\"mtk1\"> @</span><span class=\"mtk12\">types</span><span class=\"mtk1\">/</span><span class=\"mtk12\">express</span><span class=\"mtk1\">-</span><span class=\"mtk12\">session</span></span></code></pre>\n<p>When the installation is completed, go to your <code>main.ts</code> file, the root of your application, and do the configurations there.</p>\n<p>Import everything from <code>passport</code> and <code>express-session</code>, then add passport initialize and passport session.</p>\n<p>It is preferable to keep your secret key in your environment variables.</p>\n<p><code>main.ts</code></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=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">NestFactory</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/core&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">AppModule</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./app.module&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk4\">*</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> </span><span class=\"mtk12\">session</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;express-session&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk4\">*</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> </span><span class=\"mtk12\">passport</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;passport&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">bootstrap</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\">app</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">NestFactory</span><span class=\"mtk1\">.</span><span class=\"mtk11\">create</span><span class=\"mtk1\">(</span><span class=\"mtk12\">AppModule</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">session</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">secret:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;keyboard&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">resave:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">false</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">saveUninitialized:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">false</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\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk12\">passport</span><span class=\"mtk1\">.</span><span class=\"mtk11\">initialize</span><span class=\"mtk1\">())</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk12\">passport</span><span class=\"mtk1\">.</span><span class=\"mtk11\">session</span><span class=\"mtk1\">())</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">await</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=\"mtk7\">3000</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">bootstrap</span><span class=\"mtk1\">()</span></span></code></pre>\n<p>Add a new file, <code>authenticated.guard.ts</code>, in your <code>auth</code> folder. And create a new Guard that checks if there is a session for the user making the request — name it <code>authenticatedGuard</code>.</p>\n<p><code>authenticated.guard.ts</code></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=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">CanActivate</span><span class=\"mtk1\">, </span><span class=\"mtk12\">ExecutionContext</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Injectable</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/common&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">@</span><span class=\"mtk11\">Injectable</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">AuthenticatedGuard</span><span class=\"mtk1\"> </span><span class=\"mtk4\">implements</span><span class=\"mtk1\"> </span><span class=\"mtk10\">CanActivate</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">canActivate</span><span class=\"mtk1\">(</span><span class=\"mtk12\">context</span><span class=\"mtk1\">: </span><span class=\"mtk10\">ExecutionContext</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">request</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk11\">switchToHttp</span><span class=\"mtk1\">().</span><span class=\"mtk11\">getRequest</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\">request</span><span class=\"mtk1\">.</span><span class=\"mtk11\">isAuthenticated</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 above code, the request is gotten from the context and checked if authenticated. <code>isAuthenticated()</code> comes from <code>passport.js</code> automatically; it says. \"hey! does a session exist for this user? If so, keep going.\"</p>\n<p>To trigger the login, in your <code>users.controller.ts</code> file:</p>\n<ul>\n<li>import <code>authenticated</code> from <code>authenticated.guard.ts</code>;</li>\n<li>add the <code>useGuard</code> decorator to the <code>protected</code> route; and,</li>\n<li>pass in <code>AuthenticatedGuard</code>.</li>\n</ul>\n<p><code>users.controller.ts</code></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=\"mtk1\">    </span><span class=\"mtk15\">import</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Controller</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Get</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Post</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">UseGuards</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Request</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@nestjs/common&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk4\">*</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;bcrypt&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">AuthenticatedGuard</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;src/auth/authenticated.guard&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">LocalAuthGuard</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;src/auth/local.auth.guard&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UsersService</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./users.service&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    @</span><span class=\"mtk11\">Controller</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;users&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">UsersController</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk4\">readonly</span><span class=\"mtk1\"> </span><span class=\"mtk12\">usersService</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UsersService</span><span class=\"mtk1\">) {}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk3\">//signup</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">Post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/signup&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">addUser</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        @</span><span class=\"mtk11\">Body</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;password&#39;</span><span class=\"mtk1\">) </span><span class=\"mtk12\">userPassword</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=\"mtk11\">Body</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;username&#39;</span><span class=\"mtk1\">) </span><span class=\"mtk12\">userName</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      ) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">saltOrRounds</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">10</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\">hashedPassword</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><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\">userPassword</span><span class=\"mtk1\">, </span><span class=\"mtk12\">saltOrRounds</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">usersService</span><span class=\"mtk1\">.</span><span class=\"mtk11\">insertUser</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\">hashedPassword</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\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">msg:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;User successfully registered&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">userId:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</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\">userName:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</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=\"mtk3\">//Post / Login</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">UseGuards</span><span class=\"mtk1\">(</span><span class=\"mtk12\">LocalAuthGuard</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">Post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/login&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">login</span><span class=\"mtk1\">(@</span><span class=\"mtk11\">Request</span><span class=\"mtk1\">() </span><span class=\"mtk12\">req</span><span class=\"mtk1\">): </span><span class=\"mtk10\">any</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\">User:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">req</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\">msg:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;User logged in&#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=\"mtk3\">//Get / protected</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">UseGuards</span><span class=\"mtk1\">(</span><span class=\"mtk12\">AuthenticatedGuard</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">Get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/protected&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">getHello</span><span class=\"mtk1\">(@</span><span class=\"mtk11\">Request</span><span class=\"mtk1\">() </span><span class=\"mtk12\">req</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=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">req</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></code></pre>\n<p>At this point, it still fails because you've only configured <code>express-session</code> but didn't implement it.</p>\n<p>When a user logs in, you need to save the user in a session so that the user can access other routes with the session.</p>\n<p>One thing to keep in mind is that by default, the <code>express-session</code> library stores the session in the web server's memory.</p>\n<p>Before it goes into the session, you need to serialize the user. As it comes out of the session, deserialize the user.</p>\n<p>So, create a new file in the auth folder for serializer and deserializer, name it <code>session.serializer.ts</code>.</p>\n<p>At this point, the shape of our application <code>src</code> folder should look like this.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"34\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">    └───src</span>\n<span class=\"grvsc-line\">    │   └───auth</span>\n<span class=\"grvsc-line\">    │   │   └───auth.module.ts</span>\n<span class=\"grvsc-line\">    │   │   └───auth.service.ts</span>\n<span class=\"grvsc-line\">    │   │   └───authenticated.guard.ts</span>\n<span class=\"grvsc-line\">    │   │   └───local.auth.guard.ts</span>\n<span class=\"grvsc-line\">    │   │   └───local.strategy.ts</span>\n<span class=\"grvsc-line\">    │   │   └───session.serializer.ts</span>\n<span class=\"grvsc-line\">    │   └───users</span>\n<span class=\"grvsc-line\">    │   │   └───users.controller.ts</span>\n<span class=\"grvsc-line\">    │   │   └───users.model.ts</span>\n<span class=\"grvsc-line\">    │   │   └───users.module.ts</span>\n<span class=\"grvsc-line\">    │   │   └───users.service.ts</span>\n<span class=\"grvsc-line\">    │   └───app.controller.ts</span>\n<span class=\"grvsc-line\">    │   └───app.module.ts</span>\n<span class=\"grvsc-line\">    │   └───app.service.ts</span>\n<span class=\"grvsc-line\">    │   └───main.ts</span></code></pre>\n<p><code>session.serializer.ts</code></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=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Injectable</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/common&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">PassportSerializer</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/passport&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">@</span><span class=\"mtk11\">Injectable</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">SessionSerializer</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">PassportSerializer</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">serializeUser</span><span class=\"mtk1\">(</span><span class=\"mtk12\">user</span><span class=\"mtk1\">: </span><span class=\"mtk10\">any</span><span class=\"mtk1\">, </span><span class=\"mtk11\">done</span><span class=\"mtk1\">: (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">: </span><span class=\"mtk10\">Error</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user</span><span class=\"mtk1\">: </span><span class=\"mtk10\">any</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk10\">void</span><span class=\"mtk1\">): </span><span class=\"mtk10\">any</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">done</span><span class=\"mtk1\">(</span><span class=\"mtk4\">null</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\">deserializeUser</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">payload</span><span class=\"mtk1\">: </span><span class=\"mtk10\">any</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">done</span><span class=\"mtk1\">: (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">: </span><span class=\"mtk10\">Error</span><span class=\"mtk1\">, </span><span class=\"mtk12\">payload</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk10\">void</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ): </span><span class=\"mtk10\">any</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">done</span><span class=\"mtk1\">(</span><span class=\"mtk4\">null</span><span class=\"mtk1\">, </span><span class=\"mtk12\">payload</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>Go back to your <code>auth.module.ts</code> file, provide the <code>SessionSerializer</code>, and add the <code>register</code> method to the <code>PassportModule</code>.</p>\n<p><code>auth.module.ts</code></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=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Module</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/common&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">PassportModule</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@nestjs/passport&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UsersModule</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;src/users/users.module&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>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">LocalStrategy</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./local.strategy&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">SessionSerializer</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./session.serializer&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">@</span><span class=\"mtk11\">Module</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">imports:</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">UsersModule</span><span class=\"mtk1\">, </span><span class=\"mtk12\">PassportModule</span><span class=\"mtk1\">.</span><span class=\"mtk11\">register</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">session:</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\">providers:</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">AuthService</span><span class=\"mtk1\">, </span><span class=\"mtk12\">LocalStrategy</span><span class=\"mtk1\">, </span><span class=\"mtk12\">SessionSerializer</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">AuthModule</span><span class=\"mtk1\"> {}</span></span></code></pre>\n<p>Add some codes within the <code>LocalAuthGuard</code> in the <code>local.auth.guard.ts</code> file.</p>\n<p>Call the <code>login</code> method in <code>super</code> and pass in the request to trigger the actual login by creating a session. If you want to use sessions, you must remember to trigger the <code>super.login()</code>.</p>\n<p><code>local.auth.guard.ts</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=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">ExecutionContext</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Injectable</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@nestjs/common&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">AuthGuard</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@nestjs/passport&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    @</span><span class=\"mtk11\">Injectable</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">LocalAuthGuard</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk11\">AuthGuard</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;local&#39;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">canActivate</span><span class=\"mtk1\">(</span><span class=\"mtk12\">context</span><span class=\"mtk1\">: </span><span class=\"mtk10\">ExecutionContext</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\"> = (</span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk4\">super</span><span class=\"mtk1\">.</span><span class=\"mtk11\">canActivate</span><span class=\"mtk1\">(</span><span class=\"mtk12\">context</span><span class=\"mtk1\">)) </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> </span><span class=\"mtk10\">boolean</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">request</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk11\">switchToHttp</span><span class=\"mtk1\">().</span><span class=\"mtk11\">getRequest</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=\"mtk4\">super</span><span class=\"mtk1\">.</span><span class=\"mtk11\">logIn</span><span class=\"mtk1\">(</span><span class=\"mtk12\">request</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span></code></pre>\n<p>If you log in now, you will see the session ID stored in a cookie, which is just a key to the session store, and the cookie gets saved in the browser. The cookie is automatically attached to the rest of the request.</p>\n<p>Now that the session is working, you can access the protected route; it will return the expected user’s details.</p>\n<h2 id=\"logout-users\" style=\"position:relative;\"><a href=\"#logout-users\" aria-label=\"logout 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>Logout Users</h2>\n<p>As mentioned earlier, once a user logs out, you destroy all sessions.</p>\n<p>To log out a user, go to the <code>users.controller.ts</code> file, add a logout route, and call the <code>req.session.session()</code> method. You can return a message notifying that the user’s session has ended.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"38\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Body</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Controller</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Get</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Post</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">UseGuards</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Request</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@nestjs/common&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk4\">*</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;bcrypt&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">AuthenticatedGuard</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;src/auth/authenticated.guard&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">LocalAuthGuard</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;src/auth/local.auth.guard&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UsersService</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./users.service&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    @</span><span class=\"mtk11\">Controller</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;users&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">UsersController</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk4\">readonly</span><span class=\"mtk1\"> </span><span class=\"mtk12\">usersService</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UsersService</span><span class=\"mtk1\">) {}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk3\">//signup</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">Post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/signup&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">addUser</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        @</span><span class=\"mtk11\">Body</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;password&#39;</span><span class=\"mtk1\">) </span><span class=\"mtk12\">userPassword</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=\"mtk11\">Body</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;username&#39;</span><span class=\"mtk1\">) </span><span class=\"mtk12\">userName</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      ) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">saltOrRounds</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">10</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\">hashedPassword</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><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\">userPassword</span><span class=\"mtk1\">, </span><span class=\"mtk12\">saltOrRounds</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">usersService</span><span class=\"mtk1\">.</span><span class=\"mtk11\">insertUser</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\">hashedPassword</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\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">msg:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;User successfully registered&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">userId:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</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\">userName:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</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=\"mtk3\">//Post / Login</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">UseGuards</span><span class=\"mtk1\">(</span><span class=\"mtk12\">LocalAuthGuard</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">Post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/login&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">login</span><span class=\"mtk1\">(@</span><span class=\"mtk11\">Request</span><span class=\"mtk1\">() </span><span class=\"mtk12\">req</span><span class=\"mtk1\">): </span><span class=\"mtk10\">any</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\">User:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">req</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\">msg:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;User logged in&#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=\"mtk3\">//Get / protected</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">UseGuards</span><span class=\"mtk1\">(</span><span class=\"mtk12\">AuthenticatedGuard</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">Get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/protected&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">getHello</span><span class=\"mtk1\">(@</span><span class=\"mtk11\">Request</span><span class=\"mtk1\">() </span><span class=\"mtk12\">req</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=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">req</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=\"mtk3\">//Get / logout</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">Get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/logout&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">logout</span><span class=\"mtk1\">(@</span><span class=\"mtk11\">Request</span><span class=\"mtk1\">() </span><span class=\"mtk12\">req</span><span class=\"mtk1\">): </span><span class=\"mtk10\">any</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">session</span><span class=\"mtk1\">.</span><span class=\"mtk11\">destroy</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\">msg:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;The user session has ended&#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></code></pre>\n<p>So, once you log out, it returns a message notifying you that the user session has ended. The code for this tutorial is hosted <a href=\"https://github.com/icode247/Session-based-Auth-with-Nestjs-MongoDB-\">here</a> on my Github repository.</p>\n<h2 id=\"test-your-application\" style=\"position:relative;\"><a href=\"#test-your-application\" aria-label=\"test your application permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test Your Application</h2>\n<p>You have successfully implemented user signup, authentication, and protected the route to enable authorized access only.</p>\n<p>It’s time to test the application. If everything is in order, your server should be running. Else, restart your server with the following command:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"39\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm run start:dev</span></code></pre>\n<p>Head over to your Postman. And let’s finally test our application.</p>\n<h3 id=\"sign-up-as-a-user\" style=\"position:relative;\"><a href=\"#sign-up-as-a-user\" aria-label=\"sign up as 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>Sign Up As a User</h3>\n<p><img src=\"/f87197a117a591a4dcd924e350c53969/j38BmlHQ.webp\" alt=\"Sign Up As a User\"></p>\n<h3 id=\"log-in-as-a-user\" style=\"position:relative;\"><a href=\"#log-in-as-a-user\" aria-label=\"log in as 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>Log In As a User</h3>\n<p><img src=\"/a1da7b129971e3bf2b9cb9b2891265ec/p0GhcMPw.webp\" alt=\"Log In As a User\"></p>\n<h3 id=\"logged-in-users-cookie-id\" style=\"position:relative;\"><a href=\"#logged-in-users-cookie-id\" aria-label=\"logged in users cookie id permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Logged-in User’s Cookie ID</h3>\n<p><img src=\"/226b87a1a542b8fff954b94e5ed5646e/mPo9j3Kg.webp\" alt=\"Logged-in User’s Cookie ID\"></p>\n<h3 id=\"request-the-protected-route\" style=\"position:relative;\"><a href=\"#request-the-protected-route\" aria-label=\"request the protected 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>Request the Protected Route</h3>\n<p><img src=\"/dbde181cc57170a4abf48d50e815a1c1/kkX-6pFQ.webp\" alt=\"Request the Protected Route\"></p>\n<h3 id=\"user-logout\" style=\"position:relative;\"><a href=\"#user-logout\" aria-label=\"user logout permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>User Logout</h3>\n<p><img src=\"/7c4bf4a2305d7df71b0b42dae13e855a/UZCy1IHQ.webp\" alt=\"User Logout\"></p>\n<h2 id=\"alternatively-implement-user-authentication-with-loginradius\" style=\"position:relative;\"><a href=\"#alternatively-implement-user-authentication-with-loginradius\" aria-label=\"alternatively implement user authentication with loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Alternatively, Implement User Authentication with LoginRadius</h2>\n<p>LoginRadius provides a variety of registration and authentication services to assist you in better connecting with your consumers.</p>\n<p>On any web or mobile application, LoginRadius is the developer-friendly Identity Platform that delivers a complete set of APIs for authentication, identity verification, single sign-on, user management, and account protection capabilities like multi-factor authentication.</p>\n<p>To implement LoginRadius in your NestJS application, follow this tutorial: <a href=\"https://www.loginradius.com/blog/engineering/guest-post/nestjs-authentication-with-loginradius-api/\">NestJS User Authentication with LoginRadius API</a>.</p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>Congratulations! In this tutorial, you've learned how to implement session-based authentication in a NestJS application with the MongoDB database. You've created and authenticated a user and protected your routes from unauthorized access.</p>\n<p>You can <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/Nestjs/NestJS%20Session%20Auth\">access the sample code used in this tutorial on GitHub</a>.</p>\n<blockquote>\n<p><strong>Note:</strong> Session storage is saved by default in 'MemoryStore,' which is not intended for production use. So, while no external datastore is required for development, once in production, a data store such as <a href=\"https://redis.io/\">Redis</a> or another is suggested for stability and performance. You can <a href=\"https://www.loginradius.com/blog/async/guest-post/local-storage-vs-session-storage-vs-cookies/\">learn more about session storage here</a>.</p>\n</blockquote>\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 .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n</style>","frontmatter":{"date":"April 26, 2022","updated_date":null,"description":"Want to implement user authentication for your NestJS apps? Follow this tutorial to learn how you can implement session-based authentication for your NestJS apps along with MongoDB.","title":"NestJS: How to Implement Session-Based User Authentication","tags":["Authentication","NestJS","MongoDB","Node.js"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/c08a732623e225933ce7293ad4d43437/58556/session-based-authentication-in-nestjs.webp","srcSet":"/static/c08a732623e225933ce7293ad4d43437/61e93/session-based-authentication-in-nestjs.webp 200w,\n/static/c08a732623e225933ce7293ad4d43437/1f5c5/session-based-authentication-in-nestjs.webp 400w,\n/static/c08a732623e225933ce7293ad4d43437/58556/session-based-authentication-in-nestjs.webp 800w,\n/static/c08a732623e225933ce7293ad4d43437/99238/session-based-authentication-in-nestjs.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Ekekenta Odionyenfe Clinton","github":"icode247","avatar":null}}}},{"node":{"excerpt":"Introduction With technology evolving leaps and bounds and businesses consistently emphasizing a seamless customer experience, customer…","fields":{"slug":"/growth/how-businesses-approach-customer-security/"},"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>With technology evolving leaps and bounds and businesses consistently emphasizing a seamless customer experience, customer security is often neglected. </p>\n<p>Businesses underestimate the importance of delivering rich consumer experiences backed with robust security. They believe customers aren’t concerned about their information security and how their personal information is managed. </p>\n<p>However, a recent survey by Statista revealed that over <a href=\"https://www.statista.com/statistics/296700/personal-data-security-perception-online/\">90% of global online users</a> had at least one significant concern regarding data privacy. And around 47% of the total respondents were worried that their personal information could be exposed in a data breach. </p>\n<p>So does it mean every online business should focus more on customer security than improving overall consumer experience since balancing both aspects (security &#x26; UX) is tricky, especially when competitors are just a click away? </p>\n<p>No! Businesses can leverage a cutting-edge <a href=\"https://www.loginradius.com/blog/identity/customer-identity-and-access-management/\">consumer identity and access management</a> (CIAM) solution that creates a perfect balance between customer security and customer experience. </p>\n<p>Let’s uncover the aspects of a robust CIAM solution and how it helps businesses stay ahead of their competitors. </p>\n<h2 id=\"the-importance-of-customer-security-for-your-enterprise-and-customers\" style=\"position:relative;\"><a href=\"#the-importance-of-customer-security-for-your-enterprise-and-customers\" aria-label=\"the importance of customer security for your enterprise and customers permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Importance of Customer Security for Your Enterprise and Customers</h2>\n<p>In the past couple of years, consumers have gotten a big wake-up call about the value of their data and the risks they run if it’s leaked, stolen, or misused.</p>\n<p>Moreover, several high-profile hacks and breaches have generated widespread awareness of how negligent enterprises can be. And consumers are much more careful about which brands they do business with.</p>\n<p>On the other hand, stringent consumer privacy legislation has spread to new jurisdictions, such as the <a href=\"https://www.loginradius.com/gdpr-and-privacy/\">General Data Protection Regulation</a> (GDPR). Even the most prominent companies aren’t exempted from significant fines.</p>\n<p>If consumers don’t trust your business to protect their data and accounts, they’ll find another one. The digital world makes it easy for them to switch providers within a few clicks.</p>\n<h2 id=\"user-experience-with-robust-customer-security---the-key-to-success-in-2022-and-beyond\" style=\"position:relative;\"><a href=\"#user-experience-with-robust-customer-security---the-key-to-success-in-2022-and-beyond\" aria-label=\"user experience with robust customer security   the key to success in 2022 and beyond permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>User Experience with Robust Customer Security - The Key to Success in 2022 and Beyond</h2>\n<p>To keep pace with the ever-growing digital world, enterprises need to create a perfect harmony of a great user experience and robust security.</p>\n<p>This can be achieved by leveraging a consumer identity and access management (CIAM) solution like LoginRadius.</p>\n<p>The cutting-edge technology coupled with a great user experience from the beginning when your consumers first interact with your brand helps build consumer trust that guarantees conversion.</p>\n<p>Moreover, the best-in-class security that comes with the <a href=\"https://www.loginradius.com/\">LoginRadius Identity Platform</a> lets you assure your consumers of how vigilant you are about data privacy and security.</p>\n<h2 id=\"how-does-a-ciam-pave-the-path-for-a-rich-customer-experience-with-security\" style=\"position:relative;\"><a href=\"#how-does-a-ciam-pave-the-path-for-a-rich-customer-experience-with-security\" aria-label=\"how does a ciam pave the path for a rich customer experience with security permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 does a CIAM Pave the Path for a Rich Customer Experience with Security?</h2>\n<h3 id=\"1-omni-channel-consumer-experience\" style=\"position:relative;\"><a href=\"#1-omni-channel-consumer-experience\" aria-label=\"1 omni channel consumer experience permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>#1. Omni-channel consumer experience</h3>\n<p>An omnichannel consumer experience refers to seamless interaction across multiple channels. Consumer expectations fall into speed, flexibility, reliability, and transparency.</p>\n<p>For example, it is omnichannel when marketing, sales, consumer support, and even in-store experiences are synced up so users can seamlessly switch channels and make the purchase.</p>\n<p><a href=\"https://www.loginradius.com/resource/making-customers-feel-seen-in-an-omnichannel-world/\"><img src=\"/d5d452c185b8b02d0349db4bfacccd22/EB-omnichannel.webp\" alt=\"EB-omnichannel\"></a></p>\n<h3 id=\"2-single-consumer-view\" style=\"position:relative;\"><a href=\"#2-single-consumer-view\" aria-label=\"2 single consumer view permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>#2. Single consumer view</h3>\n<p>A single consumer view (also known as SCV) is where all consumers' data is stored securely and presented as an easy-to-read record.</p>\n<p>That may include the basic information about a consumer, the past and present purchasing data, interactions with customer service, and their social media behavior under a single admin panel. It assists brands in having an in-depth insight into their consumers.</p>\n<h3 id=\"3-the-highest-level-of-customer-security\" style=\"position:relative;\"><a href=\"#3-the-highest-level-of-customer-security\" aria-label=\"3 the highest level of customer security permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>#3. The highest level of customer security</h3>\n<p>In an age where sensational hacking and malicious attacks have become the order of the day, enhanced safeguard against the ever-looming threats is indispensable.</p>\n<p>By adding multiple layers of shields in the form of multi-factor authentication (MFA) and risk-based authentication (RBA), the <a href=\"https://www.loginradius.com/blog/identity/new-age-ciam/\">new-age CIAM</a> strengthens security. Thus, the entire cluster of data remains protected from the prying eyes or, for that matter, falling prey to data trackers. </p>\n<h2 id=\"why-should-businesses-rely-on-loginradius-ciam\" style=\"position:relative;\"><a href=\"#why-should-businesses-rely-on-loginradius-ciam\" aria-label=\"why should businesses rely on loginradius ciam permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Why Should Businesses Rely on LoginRadius CIAM?</h2>\n<p>LoginRadius' modern CIAM solution is designed to be more flexible and intuitive. It addresses every subtle component that can improve consumers' experience while also providing an unmatched safeguard for private data.</p>\n<p>What puts LoginRadius ahead of the curve are the three most fundamental aspects:</p>\n<ul>\n<li><strong>Frictionless security:</strong> Strengthened security doesn't have to come at the cost of convenience. LoginRadius' modern CIAM solution like MFA, passwordless login, phone login, <a href=\"https://www.loginradius.com/social-login/\">social login</a>, etc., ensures no friction while authenticating.</li>\n<li><strong>Privacy management:</strong> Proficient privacy management is the key to winning consumers' trust. Our new-age CIAM solution considers every subtle privacy concern related to international regulations like the GDPR and the CCPA.</li>\n<li><strong>Seamless integration:</strong> Another feature that sets LoginRadius' new-age CIAM apart is the seamless integration with the modern tools geared to offer smooth and secure access.</li>\n</ul>\n<h2 id=\"the-bottom-line\" style=\"position:relative;\"><a href=\"#the-bottom-line\" aria-label=\"the bottom line permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Bottom Line</h2>\n<p>With the high number of cybersecurity threats affecting global businesses, it’s high time business leaders need to incorporate stringent security mechanisms to ensure consumer data remains secure. </p>\n<p>Moreover, at the same time, equal emphasis should be given to delivering rich consumer experiences since today’s consumers are always seeking great usability across every online platform. </p>\n<p>Hence, the critical role of a CIAM solution in enhancing customer security and improving consumer experience can’t be overlooked. </p>\n<p>Businesses need to invoke the potential of a reliable CIAM like LoginRadius to ensure they get perfect harmony of user experience and security. </p>\n<p><a href=\"https://www.loginradius.com/contact-us?utm_source=blog&#x26;utm_medium=web&#x26;utm_campaign=how-businesses-approach-customer-security\"><img src=\"/8fce571f703a5970dbb1359a2fe0e51a/book-a-demo-loginradius.webp\" alt=\"book-free-demo-loginradius\"></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</style>","frontmatter":{"date":"April 22, 2022","updated_date":null,"description":"Customer security is crucial for any business striving to stay ahead of the competition. However, balancing customer security with a rich consumer experience is what it all takes to propel growth. Learn the aspects of a robust CIAM solution and how it helps businesses stay ahead of their competitors.","title":"How Should Growth-Minded Enterprises Approach Customer Security?","tags":["data security","compliance","ciam","customer experience"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.6,"src":"/static/e193f646ae4ac7bc553042b2dc16ba4f/7f8e9/growth-comp.webp","srcSet":"/static/e193f646ae4ac7bc553042b2dc16ba4f/61e93/growth-comp.webp 200w,\n/static/e193f646ae4ac7bc553042b2dc16ba4f/1f5c5/growth-comp.webp 400w,\n/static/e193f646ae4ac7bc553042b2dc16ba4f/7f8e9/growth-comp.webp 768w","sizes":"(max-width: 768px) 100vw, 768px"}}},"author":{"id":"Rakesh Soni","github":"oyesoni","avatar":"rakesh-soni.webp"}}}},{"node":{"excerpt":"Introduction Phishing attacks aren’t uncommon, and we’ve all witnessed fake emails and messages that demand urgent attention at least once…","fields":{"slug":"/identity/what-is-browser-in-browser-attack/"},"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>Phishing attacks aren’t uncommon, and we’ve all witnessed fake emails and messages that demand urgent attention at least once. However, there’s much more in the cybersecurity landscape than just conventional email practices when it comes to phishing. </p>\n<p>A <a href=\"https://www.loginradius.com/blog/identity/phishing-for-identity/\">phishing attack</a> can be a death blow for enterprises that don't take the necessary precautions. The top line is affected, but the brand's image and trust can be obliterated if news of a data breach reaches the public.</p>\n<p>The browser in the browser attack (BITB) is the latest form of phishing scam that simulates a browser window within a web browser and steals sensitive user information. </p>\n<p>The user is catered with a fraudulent pop-up window that asks for their credentials for signing into the website in the previous web browser window and thus leads to identity theft. </p>\n<p>Let’s understand the aspects of Browser in-browser attacks and how businesses can ensure stringent security for their consumers and employees to protect against these attacks. </p>\n<h2 id=\"what-is-browser-in-the-browser-attacks-who-all-are-at-a-higher-risk\" style=\"position:relative;\"><a href=\"#what-is-browser-in-the-browser-attacks-who-all-are-at-a-higher-risk\" aria-label=\"what is browser in the browser attacks who all are at a higher risk permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Browser in the Browser Attacks? Who all are at a Higher Risk?</h2>\n<p>Whenever a user chooses a <a href=\"https://www.loginradius.com/blog/identity/what-is-single-sign-on/\">single sign-on (SSO)</a> option in a website or web application for signing in to their account for multiple interconnected applications, the fraudulent pop-up will be displayed to collect sensitive information about the user, including login credentials. </p>\n<p>Moreover, the significant difference between a phishing scam and a BIBT attack is that the pop-up window during the sign-in process would show any URL that matches the authentic one.</p>\n<p>In a nutshell, cybercriminals simulate a web browser window within a web browser for spoofing a legitimate domain. This attack majorly exploits the single sign-on (SSO) option, which users always prefer to stay logged in to different interconnected websites or applications.</p>\n<p>Users don’t wish to remember long credentials. They are hesitant to provide their credentials again and again, which gives an advantage to cybercriminals as they exploit the single sign-on login preference since users can’t differentiate between a fake domain or a legitimate one once a pop-up window appears. </p>\n<p>Various businesses offering single sign-on to their consumers for a seamless user experience across their multiple applications are always at a higher risk of compromising sensitive consumer information by falling prey to these browsers in the browser attacks. </p>\n<p>However, the businesses offering SSO capabilities must understand the risks associated with SSO and incorporate stringent security mechanisms to protect their consumer information. </p>\n<h2 id=\"how-businesses-can-avoid-browser-in-the-browser-attacks\" style=\"position:relative;\"><a href=\"#how-businesses-can-avoid-browser-in-the-browser-attacks\" aria-label=\"how businesses can avoid browser in the browser attacks permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Businesses Can Avoid Browser in the Browser Attacks</h2>\n<p>Since SSO has provided endless opportunities to businesses and consumers, avoiding the use of SSO isn’t a great option at all. </p>\n<p>Adding multiple layers of security while implementing single sign-on (SSO) could help businesses prevent browser in the browser attacks and help mitigate other associated risks. </p>\n<p><a href=\"https://www.loginradius.com/resource/loginradius-single-sign-on/\"><img src=\"/970abf5b3c4e78379ad5bf97a519b62c/DS-SSO.webp\" alt=\"DS-SSO\"></a></p>\n<p>Let’s understand how businesses can reinforce security against BITB attacks. </p>\n<h3 id=\"incorporating-multi-factor-authentication-mfa\" style=\"position:relative;\"><a href=\"#incorporating-multi-factor-authentication-mfa\" aria-label=\"incorporating multi factor authentication mfa permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Incorporating multi-factor authentication (MFA)</h3>\n<p><a href=\"https://www.loginradius.com/blog/identity/what-is-multi-factor-authentication/\">Multi-factor authentication</a> (or MFA)  is a multi-layered security system that verifies the identity of users for login or other transactions.</p>\n<p>By leveraging multiple authentication layers, the user account will remain secure even if one element is damaged or disabled. </p>\n<p>Codes generated by smartphone apps, answers to personal security questions, codes sent to an email address, fingerprints, etc., are a few examples of multi-factor authentication implemented in day-to-day scenarios.</p>\n<p>Adding MFA to your security policy could prevent your users from compromising their identities during a browser in the browser attack but also helps ensure robust safety for your sensitive business information. </p>\n<p>The use of software and even hardware tokens for dual identity verification is a highly-efficient way of reinforcing security against BITB attacks. </p>\n<h3 id=\"choosing-risk-based-authentication-rba\" style=\"position:relative;\"><a href=\"#choosing-risk-based-authentication-rba\" aria-label=\"choosing risk based authentication rba permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Choosing risk-based authentication (RBA)</h3>\n<p>Risk-based authentication or <a href=\"https://www.loginradius.com/blog/identity/adaptive-authentication/\">adaptive authentication</a> is the one-stop solution for preventing browser in the browser attacks. </p>\n<p>RBA is a method of applying various levels of stringency to authentication processes based on the likelihood that access to a given system could be compromised. As the level of risk increases, authentication becomes more restrictive.</p>\n<p>Hence, RBA automatically incorporates another layer of authentication in a high-risk situation like a BITB attack, and the user’s identity remains protected. </p>\n<p>Risk-based authentication can be incorporated through a cloud-based consumer identity and access management (CIAM) platform that restricts unauthorized access even if the users leverage single sign-on capabilities. </p>\n<h2 id=\"zero-trust-architecture\" style=\"position:relative;\"><a href=\"#zero-trust-architecture\" aria-label=\"zero trust architecture permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Zero trust architecture</h2>\n<p>Zero trust is the security concept based on a belief that enterprises shouldn’t automatically trust any device or individual, whether inside or outside its perimeters and strictly verify everything before granting access.</p>\n<p>In a nutshell, <a href=\"https://www.loginradius.com/resource/zero-trust-security/\">zero trust</a> relies on the principle of “don’t trust anyone.” This architecture cuts all the access points until proper verification is done and trust is established.</p>\n<p>No access is provided until the system verifies the individual or device demanding access to the IP address, device, or storage. </p>\n<h2 id=\"final-thoughts\" style=\"position:relative;\"><a href=\"#final-thoughts\" aria-label=\"final thoughts permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Final Thoughts</h2>\n<p>Since global businesses face enormous challenges when it comes to ensuring robust security for their consumers, relying on MFA, RBA, and zero trust architecture can provide the highest level of security when it comes to preventing browser in the browser attacks. </p>\n<p>Businesses can choose a reliable <a href=\"https://www.loginradius.com/\">CIAM solution</a> like LoginRadius that helps brands secure their consumer identities by leveraging the true potential of multi-factor authentication, risk-based authentication, and zero trust architecture. </p>\n<p>If you wish to see the future of CIAM in action and understand how it works for your brand, reach us to schedule a personalized demo. </p>\n<p><a href=\"https://www.loginradius.com/contact-us?utm_source=blog&#x26;utm_medium=web&#x26;utm_campaign=what-is-browser-in-browser-attack\"><img src=\"/8fce571f703a5970dbb1359a2fe0e51a/book-a-demo-loginradius.webp\" alt=\"book-a-demo-loginradius\"></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</style>","frontmatter":{"date":"April 22, 2022","updated_date":null,"description":"The browser in the browser attack (BITB) is the latest form of phishing scam that simulates a browser window within a web browser and steals sensitive user information. Let’s understand the aspects of Browser in-browser attacks and how businesses can ensure stringent security for their consumers and employees to protect against these attacks.","title":"BITB Attacks: The New Destructive Phishing Technique","tags":["phishing","sso","identity-theft","mfa"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5267175572519085,"src":"/static/7f778f575cf9715afd3f6fb39f034320/58556/bib-attacks.webp","srcSet":"/static/7f778f575cf9715afd3f6fb39f034320/61e93/bib-attacks.webp 200w,\n/static/7f778f575cf9715afd3f6fb39f034320/1f5c5/bib-attacks.webp 400w,\n/static/7f778f575cf9715afd3f6fb39f034320/58556/bib-attacks.webp 800w,\n/static/7f778f575cf9715afd3f6fb39f034320/99238/bib-attacks.webp 1200w,\n/static/7f778f575cf9715afd3f6fb39f034320/587c8/bib-attacks.webp 1542w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Gurjyot Singh","github":null,"avatar":null}}}},{"node":{"excerpt":"Introduction With enterprises inclining towards a cookieless business landscape, managing privacy and compliance with transparency become…","fields":{"slug":"/growth/manage-privacy-compliance-in-cookieless-world/"},"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>With enterprises inclining towards a cookieless business landscape, managing privacy and compliance with transparency become the need of the hour. </p>\n<p>Moreover, various legislation, including <a href=\"https://www.loginradius.com/blog/identity/ccpa-vs-gdpr-the-compliance-war/\">EU’s GDPR and California’s CCPA</a>, are becoming increasingly stringent regarding businesses collecting, storing, and managing consumer information. </p>\n<p>Hence, businesses need to gear up for the new reality and ensure they create a perfect harmony while adhering to the regulatory compliances and delivering a seamless user experience simultaneously. </p>\n<p>But, how would businesses swiftly adopt the change? Because almost every business is reliant on cookies for personalized user experiences and going cookieless all of a sudden could be stressful. </p>\n<p>So, how can businesses adopt this new shift while ensuring they remain compliant and do not compromise  user experience while collecting crucial data? </p>\n<p>Let’s look at some crucial aspects that businesses must adapt to remain compliant and grow in a cookieless world. </p>\n<h2 id=\"what-does-cookieless-mean-wholl-be-impacted\" style=\"position:relative;\"><a href=\"#what-does-cookieless-mean-wholl-be-impacted\" aria-label=\"what does cookieless mean wholl be impacted permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Does Cookieless Mean? Who’ll be Impacted?</h2>\n<p>Before learning about cookieless, let's understand what cookies are and how they’re helping businesses derive growth. </p>\n<p>Cookies are small portions of data stored on a user’s web browser, and websites utilize these cookies to enhance user experience through personalization. </p>\n<p>Businesses have been using cookies for decades since they help them understand their consumers better and further help them plan a winning strategy for their business growth. </p>\n<p>Now talking about going cookieless describes a marketing process through which marketers aren’t relying much on cookies. In a nutshell, cookies aren’t collected for marketing purposes. </p>\n<p>The multinational technology giant Apple has already adopted the cookieless architecture. Apple’s Safari web browser is considered the only web browser that delivers the highest level of privacy to its users. </p>\n<p>However, just like Safari, Google has also planned to jump on the cookieless bandwagon and is working to enhance privacy and compliance for its users. </p>\n<p>So, what does this entire scenario portray? </p>\n<p>Though consumers are concerned about how their data is used online and demand more control over it, major companies are already blocking third-party cookies, thus impacting customer privacy and compliance. </p>\n<p>However, on the other hand, blocking third-party cookies that are majorly used for marketing, personalization, and new customer acquisition purposes would undoubtedly impact many businesses online. </p>\n<p>Since we’ve discussed all the aspects of a cookieless world, let’s talk about what online businesses can do to prosper and <a href=\"https://www.loginradius.com/blog/identity/how-loginradius-helps-enterprises-stay-ccpa-compliant-in-2020/\">stay compliant</a>.</p>\n<h3 id=\"1-transparency-leads-to-consumer-trust\" style=\"position:relative;\"><a href=\"#1-transparency-leads-to-consumer-trust\" aria-label=\"1 transparency leads to consumer trust permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>#1. Transparency leads to consumer trust.</h3>\n<p>One of the crucial aspects that business owners need to understand is that transparency is the key to <a href=\"https://www.loginradius.com/customer-security/\">winning consumer trust</a>. </p>\n<p>Trust has to be earned, for which online businesses should be transparent about the collection, storage, and use of consumer data. </p>\n<p>Unless businesses don’t offer complete transparency, earning consumer trust would be an uphill battle since the ones offering full transparency would be on the right path to meeting the privacy and compliance regulations and would eventually have users that share their details without any hassle. </p>\n<h3 id=\"2-incorporating-progressive-profiling\" style=\"position:relative;\"><a href=\"#2-incorporating-progressive-profiling\" aria-label=\"2 incorporating progressive profiling permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>#2. Incorporating progressive profiling.</h3>\n<p>Since businesses won’t be able to rely much on cookies, progressive profiling could be the game-changer for them as it allows users to gather crucial information gradually. </p>\n<p>Progressive profiling is the method of collecting personal information about the client step-by-step. It helps the digital marketing team streamline the lead nurturing process by gathering increasingly specific client data without hampering privacy and compliance regulations. </p>\n<p><a href=\"https://www.loginradius.com/resource/how-to-squeeze-every-drop-of-progressive-profiling/\"><img src=\"/0043785bf2e3f481635df5ab85c16842/EB-progressive-profiling.webp\" alt=\"EB-progressive-profiling\"></a></p>\n<p>Progressive profiling allows marketers to collect critical information about their clientele and build unique consumer personas. It helps determine where a particular consumer is in the buying journey and decide the best course of action to move them towards the final purchasing stage.</p>\n<p>And yes, all these things can be done by taking the user's consent so that they need not worry regarding their privacy. </p>\n<h3 id=\"3-crafting-rich-consumer-experience\" style=\"position:relative;\"><a href=\"#3-crafting-rich-consumer-experience\" aria-label=\"3 crafting rich consumer experience permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>#3. Crafting rich consumer experience.</h3>\n<p>A rich consumer experience can help businesses build trust, encouraging them to share their data even if cookies aren’t collected. </p>\n<p>As we all know that the attention span of users is decreasing consistently, businesses that aren’t able to impress their users in a couple of seconds would lose the game. </p>\n<p>Hence, businesses relying on conventional user interfaces that bombard users with a lengthy registration form would lag behind their competitors. An intelligent user interface that collects data gradually by adhering to the <a href=\"https://www.loginradius.com/customer-privacy/\">privacy and compliance regulations</a> and doesn’t hamper user experience is undeniably the need of the hour. </p>\n<p>In a nutshell, businesses can ask for users’ consent if they deliver them a flawless user interface where users can quickly access the consent banner and customize their preferences. </p>\n<h2 id=\"final-thoughts\" style=\"position:relative;\"><a href=\"#final-thoughts\" aria-label=\"final thoughts permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Final Thoughts</h2>\n<p>The cookieless world isn’t hyped since more and more web browsers are following the trend ever since Apple’s Safari has taken stringent measures regarding the collection of third-party cookies. </p>\n<p>Businesses that deliver personalized experiences based on user cookies would now have to find alternatives. Hence, the aspects mentioned above could help them deliver rich consumer experiences and maintain privacy and compliance even in challenging situations. </p>\n<p><a href=\"https://www.loginradius.com/contact-us?utm_source=blog&#x26;utm_medium=web&#x26;utm_campaign=manage-privacy-compliance-in-cookieless-world\"><img src=\"/8fce571f703a5970dbb1359a2fe0e51a/book-a-demo-loginradius.webp\" alt=\"book-free-demo-loginradius\"></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</style>","frontmatter":{"date":"April 20, 2022","updated_date":null,"description":"Businesses need to gear up for the new reality and ensure they create a perfect harmony while adhering to the privacy and compliances while delivering a seamless user experience simultaneously. Let’s look at some crucial aspects that businesses must adapt to remain compliant and grow in a cookieless world.","title":"Managing Privacy and Compliance in a Cookieless World","tags":["data security","privacy","compliance","progressive profiling"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5625,"src":"/static/93e5c9825bd69913fbd854b7431604ba/7f8e9/cookieless-world.webp","srcSet":"/static/93e5c9825bd69913fbd854b7431604ba/61e93/cookieless-world.webp 200w,\n/static/93e5c9825bd69913fbd854b7431604ba/1f5c5/cookieless-world.webp 400w,\n/static/93e5c9825bd69913fbd854b7431604ba/7f8e9/cookieless-world.webp 768w","sizes":"(max-width: 768px) 100vw, 768px"}}},"author":{"id":"Rakesh Soni","github":"oyesoni","avatar":"rakesh-soni.webp"}}}}]},"markdownRemark":{"excerpt":"Identity is evolving, and developers are at the forefront of this transformation. Every day brings a new learning—adapting to new standards…","fields":{"slug":"/identity/developer-first-identity-provider-loginradius/"},"html":"<p>Identity is evolving, and developers are at the forefront of this transformation. Every day brings a new learning—adapting to new standards and refining approaches to building secure, seamless experiences.</p>\n<p>We’re here to support developers on that journey. We know how important simplicity, efficiency, and well-structured documentation are when working with identity and access management solutions. That’s why we’ve redesigned the <a href=\"https://www.loginradius.com/\">LoginRadius website</a>—to be faster, more intuitive, and developer-first in every way.</p>\n<p>The goal? Having them spend less time searching and more time building.</p>\n<h2 id=\"whats-new-and-improved-on-the-loginradius-website\" style=\"position:relative;\"><a href=\"#whats-new-and-improved-on-the-loginradius-website\" aria-label=\"whats new and improved on the loginradius website permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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’s New and Improved on the LoginRadius Website?</h2>\n<p>LoginRadius’ vision is to give developers a product that simplifies identity management so they can focus on building, deploying, and scaling their applications. To enhance this experience, we’ve spent the last few months redesigning our interface— making navigation more intuitive and reassuring that essential resources are easily accessible.</p>\n<p>Here’s a closer look at what’s new and why it’s important:</p>\n<h3 id=\"a-developer-friendly-dark-theme\" style=\"position:relative;\"><a href=\"#a-developer-friendly-dark-theme\" aria-label=\"a developer friendly dark theme permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Developer-Friendly Dark Theme</h3>\n<p><img src=\"/f46881583c7518a93bb24e94c32320de/a-developer-friendly-dark-theme.webp\" alt=\"This image shows how LoginRadius offers several authentication methods like traditional login, social login, passwordless login, passkeys and more in a dark mode.\">    </p>\n<p>Developers spend long hours working in dark-themed IDEs and terminals, so we’ve designed the LoginRadius experience to be developer-friendly and align with that preference.</p>\n<p>The new dark mode reduces eye strain, enhances readability, and provides a seamless transition between a coding environment and our platform. Our new design features a clean, modern aesthetic with a consistent color scheme and Barlow typography, ensuring better readability. High-quality graphics and icons are thoughtfully placed to enhance the content without adding visual clutter.</p>\n<p>So, whether you’re navigating our API docs or configuring authentication into your system, our improved interface will make those extended development hours more comfortable and efficient.</p>\n<h3 id=\"clear-categorization-for-loginradius-capabilities\" style=\"position:relative;\"><a href=\"#clear-categorization-for-loginradius-capabilities\" aria-label=\"clear categorization for loginradius capabilities permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Clear Categorization for LoginRadius Capabilities</h3>\n<p><img src=\"/e5358b82be414940f3fb146013845933/capabilities.webp\" alt=\"This image shows a breakdown of all the LoginRadius CIAM capabilities, including authentication, security, UX, scalability and multi-brand management.\"></p>\n<p>We’ve restructured our website to provide a straightforward breakdown of our customer identity and access management platform capabilities, helping you quickly find what you need:</p>\n<ul>\n<li>Authentication: Easily understand <a href=\"https://www.loginradius.com/blog/identity/authentication-option-for-your-product/\">how to choose the right login method</a>, from traditional passwords and OTPs to social login, federated SSO, and passkeys with few lines of code.</li>\n<li>Security: Implement no-code security features like bot detection, IP throttling, breached password alerts, DDoS protection, and adaptive MFA to safeguard user accounts.</li>\n<li>User Experience: Leverage AI builder, hosted pages, and drag-and-drop workflows to create smooth, branded sign-up and login experiences.</li>\n<li>High Performance &#x26; Scalability: Confidently scale with sub-100ms API response times, 100% uptime, 240K+ RPS, and 28+ global data center regions.</li>\n<li>Multi-Brand Management: Efficiently manage multiple identity apps, choosing isolated or shared data stores based on your brand’s unique needs.</li>\n</ul>\n<p>This structured layout ensures you can quickly understand each capability and how it integrates into your identity ecosystem.</p>\n<h3 id=\"developer-first-navigation\" style=\"position:relative;\"><a href=\"#developer-first-navigation\" aria-label=\"developer first navigation permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Developer-First Navigation</h3>\n<p><img src=\"/a8c155c2b6faf3d5f4b4de4e2b14d763/developers-menu.webp\" alt=\"This image shows the LoginRadius menu bar, highlighting the developer dropdown.\">   </p>\n<p>We’ve been analyzing developer workflows to identify how you access key resources. That’s why we redesigned our navigation with one goal in mind: to reduce clicks and make essential resources readily available.</p>\n<p>The new LoginRadius structure puts APIs, SDKs, and integration guides right at the menu bar under the Developers dropdown so you can get started faster. Our Products, Solutions, and Customer Services are also clearly categorized, helping development teams quickly find the right tools and make informed decisions.</p>\n<h3 id=\"quick-understanding-of-integration-benefits\" style=\"position:relative;\"><a href=\"#quick-understanding-of-integration-benefits\" aria-label=\"quick understanding of integration benefits permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Quick Understanding of Integration Benefits</h3>\n<p><img src=\"/b2f9a964a2da0ea83e2f8596b833bba7/we-support-your-tech-stack.webp\" alt=\"This image shows a list of popular programming languages and frameworks offered by LoginRadius.\"></p>\n<p>Developers now have a clear view of the tech stack available with LoginRadius, designed to support diverse business needs.</p>\n<p>Our platform offers pre-built SDKs for Node.js, Python, Java, and more, making CIAM integration seamless across popular programming languages and frameworks.</p>\n<h2 id=\"over-to-you-now\" style=\"position:relative;\"><a href=\"#over-to-you-now\" aria-label=\"over to you now permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Over to You Now!</h2>\n<p>Check out our <a href=\"https://www.loginradius.com/\">revamped LoginRadius website</a> and see how the improved experience makes it easier to build, scale, and secure your applications.</p>\n<p>Do not forget to explore the improved navigation and API documentation, and get started with our free trial today. We’re excited to see what you’ll build with LoginRadius!</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":"February 21, 2025","updated_date":null,"description":"LoginRadius’ vision is to give developers a product that simplifies identity management so they can focus on building, deploying, and scaling their applications. To enhance this experience, we’ve redesigned our website interface, making navigation more intuitive and reassuring that essential resources are easily accessible.","title":"Revamped & Ready: Introducing the New Developer-First LoginRadius Website","tags":["Developer tools","API","Identity Management","User Authentication"],"pinned":true,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7857142857142858,"src":"/static/80b4e4fbe176a10a327d273504607f32/58556/hero-section.webp","srcSet":"/static/80b4e4fbe176a10a327d273504607f32/61e93/hero-section.webp 200w,\n/static/80b4e4fbe176a10a327d273504607f32/1f5c5/hero-section.webp 400w,\n/static/80b4e4fbe176a10a327d273504607f32/58556/hero-section.webp 800w,\n/static/80b4e4fbe176a10a327d273504607f32/99238/hero-section.webp 1200w,\n/static/80b4e4fbe176a10a327d273504607f32/7c22d/hero-section.webp 1600w,\n/static/80b4e4fbe176a10a327d273504607f32/1258b/hero-section.webp 2732w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Rakesh Soni","github":"oyesoni","avatar":"rakesh-soni.webp"}}}},"pageContext":{"limit":6,"skip":282,"currentPage":48,"type":"///","numPages":164,"pinned":"ee8a4479-3471-53b1-bf62-d0d8dc3faaeb"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}