{"componentChunkName":"component---src-templates-blog-list-template-js","path":"/engineering/4","result":{"data":{"allMarkdownRemark":{"edges":[{"node":{"excerpt":"Finding it challenging to integrate invisible reCAPTCHA only on specific web pages? This short tutorial helps you implement invisible…","fields":{"slug":"/engineering/integrate-invisible-captcha-for-bot-protection/"},"html":"<p>Finding it challenging to integrate invisible reCAPTCHA only on specific web pages? This short tutorial helps you implement invisible reCAPTCHA at specific and distinct containers, such as login and forgot password. This tutorial uses LoginRadius to demonstrate this.</p>\n<blockquote>\n<p>You can <a href=\"https://accounts.loginradius.com/auth.aspx?plan=developer&#x26;action=register\">quickly create a free LoginRadius account here</a>.</p>\n</blockquote>\n<h2 id=\"what-is-recaptcha\" style=\"position:relative;\"><a href=\"#what-is-recaptcha\" aria-label=\"what is recaptcha permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 reCAPTCHA?</h2>\n<p><a href=\"https://www.google.com/recaptcha/about/\">Google reCAPTCHA</a> is a security service that helps protect your websites from fraud and abuse.</p>\n<p>Currently, LoginRadius supports two different versions of <strong>Google v2reCAPTCHA</strong>.</p>\n<ul>\n<li><strong>Checkbox</strong>: In this version of v2reCaptcha, the \"I'm not a robot\" checkbox requires a user to click it to verify the user is not a robot.</li>\n<li><strong>Invisible reCAPTCHA</strong>: This version of v2reCaptcha provides a better user experience by tracking mouse movements to identify if a human is interacting with the website.</li>\n</ul>\n<h2 id=\"the-scenario\" style=\"position:relative;\"><a href=\"#the-scenario\" aria-label=\"the scenario permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Scenario</h2>\n<p>You want to enable invisible reCAPTCHA on a specific page — a login page, for demonstration. To achieve this, first <a href=\"https://dashboard.loginradius.com/login\">login to your LoginRadius dashboard</a>. Or, <a href=\"https://accounts.loginradius.com/auth.aspx?action=register\">sign up here for a free account or 21-day free trial for the Developer Pro plan</a>.</p>\n<p>If you're new to LoginRadius, <a href=\"https://www.loginradius.com/resource/loginradius-ciam-developers-whitepaper\">follow our Getting Started documentation</a>docs/references/javascript-library/getting-started/) to get going. </p>\n<h3 id=\"solution-steps\" style=\"position:relative;\"><a href=\"#solution-steps\" aria-label=\"solution steps permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Solution Steps</h3>\n<ul>\n<li>First, you need to <a href=\"https://www.loginradius.com/resource/loginradius-ciam-developers-whitepaper\">enable reCAPTCHA (Invisible reCAPTCHA) from the LoginRadius dashboard</a>docs/guide/captcha/#step-2-captcha-deployment).</li>\n<li>When you enable the invisible reCAPTCHA from the Loginradius dashboard, it will also enable the reCAPTCHA at the registration page.</li>\n<li>Now, you want to only enable invisible reCAPTCHA for enabling bot protection only on the login page.</li>\n<li>\n<p>So, you will need to do the following client-side setup for adding the invisible reCAPTCHA on a specific page only — for example, on the login page.</p>\n<ul>\n<li>Disable the reCAPTCHA using the following code before initializing the LoginRadius Object.\n<code>raasoption.invisibleRecaptcha = false;</code></li>\n<li>\n<p>Now, add the following code to render the captcha only at the login page, and here <code>beforeFormRender</code> hook is used.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">LRObject.$hooks.register(&#39;beforeFormRender&#39;, function(name, schema){</span>\n<span class=\"grvsc-line\">LRObject.options.invisibleRecaptcha = false;</span>\n<span class=\"grvsc-line\">if (name == &#39;login&#39; ) {</span>\n<span class=\"grvsc-line\">  LRObject.options.invisibleRecaptcha = true;</span>\n<span class=\"grvsc-line\">   LRObject.util.addRecaptchaJS();</span>\n<span class=\"grvsc-line\">   LRObject.util.captchaSchema(&quot;loginradius-recaptcha_widget_login&quot;, schema);</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\">});</span></code></pre>\n</li>\n</ul>\n</li>\n</ul>\n<p>The above code used the utility method <code>addRecaptchaJS</code> that adds the required JS for invisible reCAPTCHA. It also used the <code>captchaSchema</code> method to add reCAPTCHA within the Login Schema.</p>\n<ul>\n<li>\n<p>The last step is to stop resetting the reCAPTCHA before reCAPTCHA submission. So, add the following code:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">LRObject.$hooks.register(&#39;eventCalls&#39;, function(name){</span>\n<span class=\"grvsc-line\">LRObject.options.invisibleRecaptcha = false;</span>\n<span class=\"grvsc-line\">LRObject.options.optionalRecaptchaConfiguration.IsEnabled = true;</span>\n<span class=\"grvsc-line\">if (name == &#39;login&#39; ) {</span>\n<span class=\"grvsc-line\">  LRObject.options.invisibleRecaptcha = true;</span>\n<span class=\"grvsc-line\">  LRObject.options.optionalRecaptchaConfiguration.IsEnabled = false;</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\">});</span></code></pre>\n</li>\n</ul>\n<p>When you check your hosted page, invisible reCAPTCHA will appear only on the login page.</p>\n<p>Similarly, you can follow the above steps to enable invisible reCAPTCHA on the registration(signup) page or any other page.</p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>You have learned how to use invisible reCAPTCHA on specific web pages and forms with LoginRadius to improve user experience and prevent malicious bot traffic from being effective.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n</style>","frontmatter":{"date":"April 08, 2022","updated_date":null,"description":"If you only want to integrate reCAPTCHA invisibly on specific pages, LoginRadius can help you. This tutorial explains how you can quickly integrate invisible reCAPTCHA.","title":"How to Integrate Invisible reCAPTCHA for Bot Protection","tags":["reCAPTCHA","LoginRadius"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/f8a146c57decdef4899cbaa4abd69ba6/58556/configure-invisible-reCAPTCHA.webp","srcSet":"/static/f8a146c57decdef4899cbaa4abd69ba6/61e93/configure-invisible-reCAPTCHA.webp 200w,\n/static/f8a146c57decdef4899cbaa4abd69ba6/1f5c5/configure-invisible-reCAPTCHA.webp 400w,\n/static/f8a146c57decdef4899cbaa4abd69ba6/58556/configure-invisible-reCAPTCHA.webp 800w,\n/static/f8a146c57decdef4899cbaa4abd69ba6/99238/configure-invisible-reCAPTCHA.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Versha Gupta","github":"vershagupta","avatar":null}}}},{"node":{"excerpt":"Protecting customer data is paramount to every business organization. Even though businesses deploy the most stringent security measures to…","fields":{"slug":"/engineering/okta-and-the-lapsus-breach/"},"html":"<p>Protecting customer data is paramount to every business organization. Even though businesses deploy the most stringent security measures to safeguard data, malicious actors somehow find security shortcomings to access network systems and cause data breaches, compromising the confidentiality, integrity, and availability of information.</p>\n<p>Cybersecurity firms like Okta, which provides identity management solutions and deals in authentication space, make the backbone of an organization's cybersecurity posture. Okta serves 15000+ customers worldwide. The Okta data breach by Lapsus$ is a recent example of what can happen if business organizations depend on third-party solution providers who show laxity in implementing robust cybersecurity strategies, frameworks, and controls.</p>\n<p>It is also a cautionary tale for cybersecurity MSPs (Managed Services Providers) and ITSPs (IT Solution Providers) to ensure that they have the best of security controls in place to prevent incidents like this.</p>\n<h2 id=\"what-is-okta\" style=\"position:relative;\"><a href=\"#what-is-okta\" aria-label=\"what is okta permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Okta?</h2>\n<p>Okta is an identity platform and offers identity and access management solutions such as Single sign-on (SSO), Multi-Factor Authentication (MFA), etc., for an organization's customers and employees.</p>\n<h2 id=\"why-is-okta-in-the-news\" style=\"position:relative;\"><a href=\"#why-is-okta-in-the-news\" aria-label=\"why is okta in the news permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Is Okta In the News?</h2>\n<p>Okta’s CSO (Chief Security Officer) <a href=\"https://www.okta.com/blog/2022/03/updated-okta-statement-on-lapsus/\">David Bradbury</a> recently published an <a href=\"https://sec.okta.com/articles/2022/03/official-okta-statement-lapsus-claims\">official statement</a> about a support engineer whose computer was accessed by malicious actors for five days in mid-January (between January 16 to 21, 2022) and said they detected the unsuccessful attempt early on.</p>\n<h2 id=\"how-was-the-attack-executed\" style=\"position:relative;\"><a href=\"#how-was-the-attack-executed\" aria-label=\"how was the attack executed permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Was the Attack Executed?</h2>\n<p>Okta has now confirmed that malicious actors had access to one of its employees' laptops for five days in January 2022 but maintained there has been no data breach and remains fully operational. However, they concede that around <a href=\"https://www.okta.com/blog/2022/03/updated-okta-statement-on-lapsus/\">2.5% of its customers (about 366)</a> might have been affected.</p>\n<p>Here is how the attack happened.</p>\n<ul>\n<li>On March 22, 2022, a hacking group identifying itself as Lapsus$ posted some screenshots in its Telegram channel claiming to have compromised Okta's internal systems. The screenshots included Okta's Slack channels, super admin dashboard (access to reset passwords and MFA of their business customer’s employees — the customer in the screenshot was Cloudflare), and JIRA board.</li>\n<li>Okta's CSO responded through a blog post stating that the incident that Lapsus$ refers to had happened in January 2021 when it detected an attempt by hackers to compromise the account of a customer support engineer working for a third-party service provider.</li>\n<li>Okta alerted the service provider, suspended the engineer's account, and terminated the user's active Okta sessions. Besides, the company shared pertinent information with a third-party forensics firm for investigation.</li>\n<li>The investigation reported that hackers accessed the engineer's laptop for five days in January 2022.</li>\n<li>However, Lapsus$ claims that it had gained admin access to Okta's systems for two months, and it found Okta storing AWS keys in Slack channels. Furthermore, the hacker group claimed that it used its access to focus on Okta's customers.</li>\n</ul>\n<h2 id=\"who-is-behind-oktas-breach\" style=\"position:relative;\"><a href=\"#who-is-behind-oktas-breach\" aria-label=\"who is behind oktas breach permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Who Is Behind Okta’s Breach?</h2>\n<p>News reports show that a group of unscrupulous actors identifying themselves as Lapsus$ in their Telegram channel was behind this Okta breach. They were aided by a customer support engineer working for a third-party service provider whose laptop was accessed by these hackers to gain vital information. Lapsus$ is also known as a notorious threat actor group — <a href=\"https://www.microsoft.com/security/blog/2022/03/22/dev-0537-criminal-actor-targeting-organizations-for-data-exfiltration-and-destruction/\">DEV-0537</a>. This group has a history of taking over individual user accounts to drain their crypto holdings at cryptocurrency exchanges.</p>\n<h2 id=\"the-key-reasons-that-caused-the-security-breach\" style=\"position:relative;\"><a href=\"#the-key-reasons-that-caused-the-security-breach\" aria-label=\"the key reasons that caused the security breach permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Key Reasons That Caused The Security Breach</h2>\n<p>The forensics report cited by Okta's CSO did not state how the hackers managed to gain access to the support engineer’s laptop, but the fingers point towards negligence by the engineer. However, the hackers claim to have had access to Okta's systems for more than a month before the January 2022 incident. If these claims are valid, it indicates a significant security breach at Okta's network center.</p>\n<h3 id=\"okta-breach-what-was-the-impact\" style=\"position:relative;\"><a href=\"#okta-breach-what-was-the-impact\" aria-label=\"okta breach what was the impact permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Okta Breach: What Was the Impact?</h3>\n<p>The Okta breach exposed the security frailties of the Okta network system and put 15,000 Okta customers’ data at risk. However, Okta stated it had contacted the affected 2.5% of customers, appraising them of the matter. Okta further noted that the customers need not take any precautionary measures as their data is safe.</p>\n<p>The CSO blog post went on to add that the damage was restricted to the access that support engineers have, such as Jira tickets and lists of users. Though customer support engineers facilitate password resetting and MFA, the hackers did not seem to have obtained this information. The CSO also confirmed that customer service engineers could not create or delete users.</p>\n<p>Notably, Okta's customers include high-profile enterprises like FedEx Corporation and Moody's Corporation. Hence, <a href=\"https://www.reuters.com/technology/okta-says-up-366-customers-have-potentially-been-impacted-by-hacker-attack-2022-03-23/\">Okta's shares plunged 11%</a> immediately after hackers claimed the breach that has put thousands of Okta customers at risk.</p>\n<h2 id=\"what-to-learn-from-oktas-cyber-hack\" style=\"position:relative;\"><a href=\"#what-to-learn-from-oktas-cyber-hack\" aria-label=\"what to learn from oktas cyber hack permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 to Learn From Okta's Cyber Hack?</h2>\n<h3 id=\"1-limit-access-on-a-need-to-know-basis\" style=\"position:relative;\"><a href=\"#1-limit-access-on-a-need-to-know-basis\" aria-label=\"1 limit access on a need to know basis permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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) Limit Access on a ‘Need-to-Know’ Basis</h3>\n<p>Limiting access and permissions to the employees is the first step to take. Employees and contractors should only be provided access on a 'need-to-know' basis and must be provided on a ‘least privilege’ basis (minimum access needed to perform a task or job). For example, support engineers shouldn't be able to access internal HR, accounting, or payroll systems. At the same time, marketing personnel should not have access to network configuration or applications that they do not use.</p>\n<h3 id=\"2-validate-third-party-apps-and-saas-solutions\" style=\"position:relative;\"><a href=\"#2-validate-third-party-apps-and-saas-solutions\" aria-label=\"2 validate third party apps and saas solutions permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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) Validate Third-party Apps and SaaS Solutions</h3>\n<p>In an increasing multi-cloud and hybrid-cloud environment, it's paramount to understand the s IT ecosystem, third-party APIs (Application Programming Interfaces) and applications, and Software as a Service (SaaS) solutions deployed. Requesting SOC reports from vendors and contractors can help understand how their information systems are maintained and secured.</p>\n<h3 id=\"3-implement-robust-iam-pam-solutions\" style=\"position:relative;\"><a href=\"#3-implement-robust-iam-pam-solutions\" aria-label=\"3 implement robust iam pam solutions permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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) Implement Robust IAM-PAM Solutions</h3>\n<p>Implementing robust processes around Identity and Access Management (IAM) and Privileged Access Management (PAM) can help strengthen the cybersecurity posture by making it almost impossible for attackers to barge into the organization’s periphery.</p>\n<h3 id=\"4-train-employees-and-customers\" style=\"position:relative;\"><a href=\"#4-train-employees-and-customers\" aria-label=\"4 train employees 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>4) Train Employees and Customers</h3>\n<p>'People' are the most valuable asset for any organization but can also be the weakest link in the cybersecurity chain. Therefore, organizations must regularly review the processes around training and educating employees, vendor-contractors, customers, and users to follow basic cyber hygiene.</p>\n<h3 id=\"5-be-vigilant\" style=\"position:relative;\"><a href=\"#5-be-vigilant\" aria-label=\"5 be vigilant permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>5) Be Vigilant</h3>\n<p>Organizations must continue to monitor and audit the control environments. Leveraging automated monitoring and alerting tools can help overcome many challenges SOC teams face.</p>\n<h3 id=\"6-audit-and-review-regularly\" style=\"position:relative;\"><a href=\"#6-audit-and-review-regularly\" aria-label=\"6 audit and review regularly permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>6) Audit and Review Regularly</h3>\n<p>Organizations should perform internal audits and review the systems and monitor the traffic and access permission more frequently. It is also advisable to engage third-party audit firms to get an external and independent view of the cybersecurity posture.</p>\n<h3 id=\"7-communicate-transparently\" style=\"position:relative;\"><a href=\"#7-communicate-transparently\" aria-label=\"7 communicate transparently permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>7) Communicate Transparently</h3>\n<p>In case of a security incident, it is essential to be transparent to the employees, customers, vendors, and regulators and communicate with them immediately about the incident. Organizations should also provide specific guidance on how to safeguard the information assets.</p>\n<h2 id=\"to-conclude\" style=\"position:relative;\"><a href=\"#to-conclude\" aria-label=\"to conclude permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>To Conclude</h2>\n<p>The Okta breach shows that no business organization is 100% safe from malicious attacks. One simplest security issue is sufficient for malicious actors to wreak havoc.</p>\n<p>In this specific example, the hackers accessed the laptop of one of Okta's customer service engineers to gain vital insights into the company's customer data. Such incidents prove that customers can never be sure that their information is safe and leak-proof.</p>\n<p>However, it offers a valuable learning experience that business entities should not ignore the minutest of details regarding network security. It surfaces the adage that ' A chain is only as strong as its weakest link.'</p>\n<p><a href=\"https://www.loginradius.com/contact-us?utm_source=blog&#x26;utm_medium=web&#x26;utm_campaign=okta-and-the-lapsus-breach\"><img src=\"/8fce571f703a5970dbb1359a2fe0e51a/book-a-demo-loginradius.webp\" alt=\"Book a Demo\"></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":"March 25, 2022","updated_date":null,"description":"Businesses have to be extra vigilant in safeguarding customer data. Minor mistakes can cause a massive data breach, violating data privacy regulations and attracting penalties from regulatory authorities.","title":"How Lapsus$ Breached Okta and What Organizations Should Learn","tags":["Breach","Cybersecurity"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/3b10aee82003518721b8e81b9cdfb6b0/58556/how-lapsus-breached-okta.webp","srcSet":"/static/3b10aee82003518721b8e81b9cdfb6b0/61e93/how-lapsus-breached-okta.webp 200w,\n/static/3b10aee82003518721b8e81b9cdfb6b0/1f5c5/how-lapsus-breached-okta.webp 400w,\n/static/3b10aee82003518721b8e81b9cdfb6b0/58556/how-lapsus-breached-okta.webp 800w,\n/static/3b10aee82003518721b8e81b9cdfb6b0/99238/how-lapsus-breached-okta.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Kundan Singh","github":null,"avatar":null}}}},{"node":{"excerpt":"To create secure applications, you need a way to authenticate and authorize your users. In this tutorial, you will learn to authenticate…","fields":{"slug":"/engineering/guest-post/nestjs-authentication-with-loginradius-api/"},"html":"<p>To create secure applications, you need a way to authenticate and authorize your users. In this tutorial, you will learn to authenticate users in your NestJS apps using <a href=\"https://www.loginradius.com/developers/\">LoginRadius Authentication API</a>.</p>\n<h2 id=\"authentication-vs-authorization\" style=\"position:relative;\"><a href=\"#authentication-vs-authorization\" aria-label=\"authentication vs authorization permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Authentication vs. Authorization</h2>\n<p>Authentication and authorization are often seen as similar concepts, but they are not. Authentication is the process of verifying that a user is who they claim to be, while authorization is verifying which resources the user has access to.</p>\n<p>Authentication always comes first before authorization since you first need to identify the user before determining what level of access to give them.</p>\n<p>You can either choose to implement your own authentication strategy or leverage the benefits of a third-party identity platform. A do-it-yourself solution is prone to security errors, takes up a lot of time, and can increase the complexity of your application.</p>\n<p>With a third-party solution, you get access to multiple authentication methods, advanced security features, and you write less code.</p>\n<h2 id=\"user-authentication-with-loginradius\" style=\"position:relative;\"><a href=\"#user-authentication-with-loginradius\" aria-label=\"user authentication with loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>User Authentication with LoginRadius</h2>\n<p><a href=\"https://www.loginradius.com\">LoginRadius</a> is a no-code identity platform offering authentication, authorization, account security, and privacy solutions.</p>\n<p>The Authentication API provided by LoginRadius allows you to authenticate a user using an email and a password. Once the user is verified, LoginRadius responds with an access token. The user will, in turn, use the access token to send requests to protected endpoints.</p>\n<h2 id=\"user-authentication-in-nestjs\" style=\"position:relative;\"><a href=\"#user-authentication-in-nestjs\" aria-label=\"user authentication 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>User Authentication in NestJS</h2>\n<p>NestJS is a Node.js framework built on Express.js with an Angular-like architectural structure. It is used to build scalable and modern server-side applications. The following sections will guide you in creating a simple NestJS application with authentication.</p>\n<h2 id=\"set-up-the-project\" style=\"position:relative;\"><a href=\"#set-up-the-project\" aria-label=\"set up the project permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Set Up the Project</h2>\n<p>Create a new NestJS project by running the following commands</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">// Install NestJS CLI</span>\n<span class=\"grvsc-line\">npm i -g @nestjs/cli</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">// Create a new project</span>\n<span class=\"grvsc-line\">nest new nest-loginradius-auth</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">cd nest-loginradius-auth</span></code></pre>\n<h2 id=\"set-up-loginradius\" style=\"position:relative;\"><a href=\"#set-up-loginradius\" aria-label=\"set up 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>Set Up LoginRadius</h2>\n<p>To authenticate a user using LoginRadius in NestJS, you need credentials: an API key and an API secret.</p>\n<p>Get your account credentials by creating a free <a href=\"https://accounts.loginradius.com/auth.aspx?return_url=https://dashboard.loginradius.com/login&#x26;action=register\">LoginRadius account</a> and head over to the dashboard.</p>\n<p>Create an app and select configuration and then <a href=\"https://www.loginradius.com/developers/\">get your app's credentials from the API credentials panel</a>.</p>\n<h2 id=\"set-up-env-file\" style=\"position:relative;\"><a href=\"#set-up-env-file\" aria-label=\"set up env file permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 .env file</h2>\n<p>Since the API key and API secret from the LoginRadius dashboard are sensitive, you will store them in the <code>.env</code> file.</p>\n<p>You will need the dotenv module to access the your environment variables. Run the following command to install it.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">npm install dotenv</span></span></code></pre>\n<p>Add the API key, API secret, and <a href=\"https://www.loginradius.com/developers/\">Secure One Time Token(SOTT)</a> to the.env file.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">APP_NAME=&lt;your app name&gt;</span>\n<span class=\"grvsc-line\">API_KEY=&lt;your api key&gt;</span>\n<span class=\"grvsc-line\">API_SECRET=&lt;your api secret&gt;</span>\n<span class=\"grvsc-line\">SOTT= &lt;your sott&gt;</span></code></pre>\n<h2 id=\"authentication-flow\" style=\"position:relative;\"><a href=\"#authentication-flow\" aria-label=\"authentication flow permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Authentication Flow</h2>\n<p>In this project, you will be authenticating the user using their email and password. The following are the major steps you will be following:</p>\n<ul>\n<li>Create a signup route that will get the user information and create a new user.</li>\n<li>Create a login route that accepts the email and password of the user. This data will be authenticated, and an access token will be sent back in the response.</li>\n<li>Create a protected route that will only accept requests with valid access tokens.</li>\n</ul>\n<h2 id=\"create-an-authentication-module\" style=\"position:relative;\"><a href=\"#create-an-authentication-module\" aria-label=\"create an 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 an Authentication Module</h2>\n<p>Generate an auth module, controller, and service by running the following code.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">nest generate module auth</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">nest generate controller auth</span></span></code></pre>\n<h2 id=\"create-a-user\" style=\"position:relative;\"><a href=\"#create-a-user\" aria-label=\"create 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>Create a User</h2>\n<p>To create a user, you need to create a signup route that will accept the email and password.</p>\n<p>Since you are using TypeScript, define the DTO (Data Transfer Object) schema to validate the user data passed in the request body.</p>\n<p>In the <code>auth</code> folder, add the <code>dto</code> folder and create a <code>UserDTO</code> class in the <code>user.dto.ts</code> file.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">UserDto</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">email</span><span class=\"mtk1\">: </span><span 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>Next, inside the <code>AuthController</code>, import the DTO to be used to validate the request body.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">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\">UserDto</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./dto/user.dto&#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=\"mtk11\">Controller</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;auth&#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\">AuthController</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;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\">signup</span><span class=\"mtk1\">(@</span><span class=\"mtk11\">Body</span><span class=\"mtk1\">() </span><span class=\"mtk12\">registerUserDto</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UserDto</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">// Register user</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<h3 id=\"generate-auth-service-file\" style=\"position:relative;\"><a href=\"#generate-auth-service-file\" aria-label=\"generate auth service file permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Generate Auth Service File</h3>\n<p>A service file is used to abstract the business logic away from the controller. You will be handling the actual authentication and authorization process in this file.</p>\n<p>Generate a service for auth by running the following command.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">nest g service auth</span></span></code></pre>\n<p>Next, populate the auth.service file by adding the signup method.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">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\">UserDto</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./dto/user.dto&#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\">LRAuthPrrovider</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;loginradius-sdk&#39;</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\">AuthService</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\">signup</span><span class=\"mtk1\">(</span><span class=\"mtk12\">registerUserDto</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UserDto</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\">&#39;sign up&#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>Note that you are also importing the user DTO and the loginradius-sdk at the top of the file.\nTo execute the signup method in the signup route, inject it in the <code>auth.controller.ts</code> file.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">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\">UserDto</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./dto/user.dto&#39;</span><span class=\"mtk1\">;</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\">&#39;./auth.service&#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=\"mtk11\">Controller</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;auth&#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\">AuthController</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>\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\">signup</span><span class=\"mtk1\">(@</span><span class=\"mtk11\">Body</span><span class=\"mtk1\">() </span><span class=\"mtk12\">registerUserDto</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UserDto</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\">response</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\">signup</span><span class=\"mtk1\">(</span><span class=\"mtk12\">registerUserDto</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\">response</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>Before registering the user, validate if the email is already in use.\nFirst, install <code>loginradius-sdk</code> using the following command.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">npm i loginradius-sdk</span></span></code></pre>\n<p>Next import <code>loginradius-sdk</code> and configure it and since you will be using variables from the <code>.env</code> file, remember to also configure <code>dotenv</code>.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk4\">*</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> </span><span class=\"mtk12\">dotenv</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;dotenv&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">dotenv</span><span class=\"mtk1\">.</span><span class=\"mtk11\">config</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\">LRAuthPrrovider</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;loginradius-sdk&#39;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">config</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">apiDomain:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;api.loginradius.com&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">apiKey:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">process</span><span class=\"mtk1\">.</span><span class=\"mtk12\">env</span><span class=\"mtk1\">.</span><span class=\"mtk12\">API_KEY</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">apiSecret:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">process</span><span class=\"mtk1\">.</span><span class=\"mtk12\">env</span><span class=\"mtk1\">.</span><span class=\"mtk12\">API_SECRET</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">siteName:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">process</span><span class=\"mtk1\">.</span><span class=\"mtk12\">env</span><span class=\"mtk1\">.</span><span class=\"mtk12\">APP_NAME</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">apiRequestSigning:</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\">proxy:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">host:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">port:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">user:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lrv2</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">LRAuthPrrovider</span><span class=\"mtk1\">(</span><span class=\"mtk12\">config</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">sott</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">process</span><span class=\"mtk1\">.</span><span class=\"mtk12\">env</span><span class=\"mtk1\">.</span><span class=\"mtk12\">SOTT</span></span></code></pre>\n<p>Next, check if the email is already in use.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"11\"><code class=\"grvsc-code\"><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\">AuthService</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\">signup</span><span class=\"mtk1\">(</span><span class=\"mtk12\">registerUserDto</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UserDto</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">try</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">response</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lrv2</span><span class=\"mtk1\">.</span><span class=\"mtk12\">authenticationApi</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">checkEmailAvailability</span><span class=\"mtk1\">(</span><span class=\"mtk12\">registerUserDto</span><span class=\"mtk1\">.</span><span class=\"mtk12\">email</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">isExist</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=\"mtk8\">&quot;Email already in use&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">catch</span><span class=\"mtk1\">(</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">error</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 the email is not already in use, register the user.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"12\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">@</span><span class=\"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\">AuthService</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\">signup</span><span class=\"mtk1\">(</span><span class=\"mtk12\">registerUserDto</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UserDto</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">try</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk3\">// check if email is already in use</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">response</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lrv2</span><span class=\"mtk1\">.</span><span class=\"mtk12\">authenticationApi</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            .</span><span class=\"mtk11\">checkEmailAvailability</span><span class=\"mtk1\">(</span><span class=\"mtk12\">registerUserDto</span><span class=\"mtk1\">.</span><span class=\"mtk12\">email</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">isExist</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=\"mtk8\">&quot;Email already in use&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk3\">// create registration model</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">authUserRegistrationModel</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">email:</span><span class=\"mtk1\"> [</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;primary&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">value:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">registerUserDto</span><span class=\"mtk1\">.</span><span class=\"mtk12\">email</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\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">registerUserDto</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk3\">// register user</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lrv2</span><span class=\"mtk1\">.</span><span class=\"mtk12\">authenticationApi</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          .</span><span class=\"mtk11\">userRegistrationByEmail</span><span class=\"mtk1\">(</span><span class=\"mtk12\">authUserRegistrationModel</span><span class=\"mtk1\">, </span><span class=\"mtk12\">sott</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\">return</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Sign up successful&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        } </span><span class=\"mtk15\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">error</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>In the above code, you register a new user by passing in the user data to the authentication API. The <code>authUserRegistrationModel</code> object defines how the email and password will be stored in the database.</p>\n<h2 id=\"log-in-the-user\" style=\"position:relative;\"><a href=\"#log-in-the-user\" aria-label=\"log in the 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 the User</h2>\n<p>To log in the user, pass in the email and password to the authentication API of LoginRadius.</p>\n<p>In <code>auth.service.ts</code>, add the login function.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"13\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">@</span><span class=\"mtk11\">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\">AuthService</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\">signup</span><span class=\"mtk1\">(</span><span class=\"mtk12\">registerUserDto</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UserDto</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk3\">// register user</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\">login</span><span class=\"mtk1\">(</span><span class=\"mtk12\">loginUserDTO</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UserDto</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk3\">// login user</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>Since you are expecting the same type of data from the request body, i.e., the email and password, like in the signup route, you can reuse the user DTO.</p>\n<p>Next, add the login functionality.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"14\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">@</span><span class=\"mtk11\">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\">AuthService</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\">signup</span><span class=\"mtk1\">(</span><span class=\"mtk12\">registerUserDto</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UserDto</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk3\">// register user</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\">login</span><span class=\"mtk1\">(</span><span class=\"mtk12\">loginUserDTO</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UserDto</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">try</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">emailAuthenticationModel</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">email:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">loginUserDTO</span><span class=\"mtk1\">.</span><span class=\"mtk12\">email</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">loginUserDTO</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lrv2</span><span class=\"mtk1\">.</span><span class=\"mtk12\">authenticationApi</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                .</span><span class=\"mtk11\">loginByEmail</span><span class=\"mtk1\">(</span><span class=\"mtk12\">emailAuthenticationModel</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\">accessToken:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">access_token</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\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">error</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>In the above code, you are logging in the user through loginradius-sdk. If successful, send back the <code>accessToken</code> in the response body. The user will use the access token to access protected routes.</p>\n<p>Inject the login method in the <code>auth.controller.ts</code> file to use it in the login route.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"15\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"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\">UserDto</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./dto/user.dto&#39;</span><span class=\"mtk1\">;</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\">&#39;./auth.service&#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=\"mtk11\">Controller</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;auth&#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\">AuthController</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>\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\">signup</span><span class=\"mtk1\">(@</span><span class=\"mtk11\">Body</span><span class=\"mtk1\">() </span><span class=\"mtk12\">registerUserDto</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UserDto</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">// register user</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\">login</span><span class=\"mtk1\">(@</span><span class=\"mtk11\">Body</span><span class=\"mtk1\">() </span><span class=\"mtk12\">loginUserDto</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UserDto</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">// login user</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=\"access-protected-routes\" style=\"position:relative;\"><a href=\"#access-protected-routes\" aria-label=\"access protected 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>Access Protected Routes</h2>\n<p>For protected routes, like accessing a user dashboard, the user will need to send the access token with the request. The access token will then be verified, and if valid, the application will be granted access.</p>\n<p>The user will need to store the <code>accessToken</code>. In this tutorial, you will be storing the token in the authorization header as a bearer token. Another alternative would be to use HTTP-only cookies.</p>\n<p>In NestJS, guards are responsible for handling authorization. They determine whether a request will be handled by the route.</p>\n<p>In <code>auth.guard.ts</code>, add the following code.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"16\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"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=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Request</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;express&#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=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">AuthGuard</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"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>\n<span class=\"grvsc-line\"></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 class=\"mtk10\">Promise</span><span class=\"mtk1\">&lt;</span><span class=\"mtk10\">boolean</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\">request</span><span class=\"mtk1\">: </span><span class=\"mtk10\">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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk3\">// Extract the access token from the authorization header</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">authheader</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">request</span><span class=\"mtk1\">.</span><span class=\"mtk11\">header</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Authorization&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">token</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">authheader</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">authheader</span><span class=\"mtk1\">.</span><span class=\"mtk11\">split</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot; &quot;</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=\"mtk15\">try</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\">authorizedMsg</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\">authenticate</span><span class=\"mtk1\">(</span><span class=\"mtk12\">token</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk3\">// Attach the authorized message to the request. You could also attach the user information.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">request</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&#39;isAuthorized&#39;</span><span class=\"mtk1\">] = </span><span class=\"mtk8\">&quot;Authorized&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</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=\"mtk15\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>In the above code, you define the auth guard that will be used to decorate the protected routes. The token is extracted from the request authorization header and passed to the <code>authenticate</code> method defined in <code>AuthService</code>. This method will be responsible for verifying the token.</p>\n<p>In <code>auth.service.ts</code>, create the <code>authenticate</code> method. This method will send the access token to LoginRadius for verification.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"17\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"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=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UserDto</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./dto/user.dto&#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\">LRAuthPrrovider</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;loginradius-sdk&#39;</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\">AuthService</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\">signup</span><span class=\"mtk1\">(</span><span class=\"mtk12\">registerUserDto</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UserDto</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk3\">// signup user</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\">login</span><span class=\"mtk1\">(</span><span class=\"mtk12\">loginUserDTO</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UserDto</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk3\">// login user</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\">authenticate</span><span class=\"mtk1\">(</span><span class=\"mtk12\">accessToken</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\">try</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">response</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lrv2</span><span class=\"mtk1\">.</span><span class=\"mtk12\">authenticationApi</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            .</span><span class=\"mtk11\">authValidateAccessToken</span><span class=\"mtk1\">(</span><span class=\"mtk12\">accessToken</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\">response</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        } </span><span class=\"mtk15\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk15\">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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Now, create a protected route. In <code>auth.controller.ts</code>, add the following.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"18\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Controller</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Get</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Body</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Post</span><span class=\"mtk1\">, </span><span class=\"mtk12\">UseGuards</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\">UserDto</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./dto/user.dto&#39;</span><span class=\"mtk1\">;</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\">&#39;./auth.service&#39;</span><span class=\"mtk1\">;</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\">&#39;./auth.guard&#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\">Controller</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;auth&#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\">AuthController</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>\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\">signup</span><span class=\"mtk1\">(@</span><span class=\"mtk11\">Body</span><span class=\"mtk1\">() </span><span class=\"mtk12\">registerUserDto</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UserDto</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">// signup user</span></span>\n<span class=\"grvsc-line\"><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=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">login</span><span class=\"mtk1\">(@</span><span class=\"mtk11\">Body</span><span class=\"mtk1\">() </span><span class=\"mtk12\">loginUserDto</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UserDto</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">// login user</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  @</span><span class=\"mtk11\">UseGuards</span><span class=\"mtk1\">(</span><span class=\"mtk12\">AuthGuard</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=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">protected</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=\"mtk8\">&quot;Access granted&quot;</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, every route you add <code>UseGuards</code> to will require a valid access token.</p>\n<h2 id=\"test-with-postman\" style=\"position:relative;\"><a href=\"#test-with-postman\" aria-label=\"test with postman permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 with Postman</h2>\n<p>Use <a href=\"https://www.postman.com/\">Postman</a> or any other REST client of your choice to test the routes you have created.</p>\n<p>First, create a test user by sending a POST request to the signup endpoint. Remember to include the email and password of the user in the request body.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"19\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">POST http://localhost:3000/auth/signup</span></code></pre>\n<p>You should receive a \"Sign up successful\" message if the request is successful.</p>\n<p><img src=\"/c629b0b9f9d7c2a9babd4c29934fd9aa/signup-route.webp\" alt=\"Create a user\"></p>\n<p>Next, log in the user by sending the login credentials to the login endpoint of your application.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"20\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">POST http://localhost:3000/auth/login</span></code></pre>\n<p>If successful, you should receive the access token.</p>\n<p><img src=\"/8c2450f6f8cd95eadbd9d5ef63256c06/login-route.webp\" alt=\"Sign up a user\"></p>\n<p>Finally, use the access token to access the protected route. Add the token to the authorization header.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"21\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">GET http://localhost:3000/auth/protected</span></code></pre>\n<p><img src=\"/c06de4f99d2b0cda2772852de3a873a6/protected-route.webp\" alt=\"Sign up a user\"></p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>In this tutorial, you have learned how to implement NestJS authentication using the LoginRadius Authentication API. You have seen how to log in a user and use an access token to protect specific routes.</p>\n<p>You can <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/NestJS/nestjs-authentication-loginradius-api\">find the source code used in this tutorial on Github</a>.</p>\n<p>Learn more about the <a href=\"https://www.loginradius.com/developers/\">LoginRadius Authentication API</a> from the documentation files. It has more identity management features than discussed in this tutorial. You can use these features to further enhance authentication as you need in your NestJS projects.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\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 .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n</style>","frontmatter":{"date":"March 23, 2022","updated_date":null,"description":"Want to authenticate users on your NestJS app? Follow this tutorial to learn how to authenticate users using a password and perform authorization using access tokens.","title":"NestJS User Authentication with LoginRadius API","tags":["NestJS","Node.js","Authentication"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/ff122b5b50ce0f2b3f855935f99838f6/58556/coverimage.webp","srcSet":"/static/ff122b5b50ce0f2b3f855935f99838f6/61e93/coverimage.webp 200w,\n/static/ff122b5b50ce0f2b3f855935f99838f6/1f5c5/coverimage.webp 400w,\n/static/ff122b5b50ce0f2b3f855935f99838f6/58556/coverimage.webp 800w,\n/static/ff122b5b50ce0f2b3f855935f99838f6/99238/coverimage.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Mary Gathoni","github":null,"avatar":null}}}},{"node":{"excerpt":"In this tutorial, I’ll talk about adding authentication in a Svelte application using LoginRadius Authentication APIs. You'll understand…","fields":{"slug":"/engineering/guest-post/authenticating-svelte-apps/"},"html":"<p>In this tutorial, I’ll talk about adding authentication in a Svelte application using LoginRadius Authentication APIs. You'll understand step by step how to:</p>\n<ul>\n<li>create forms in Svelte;</li>\n<li>add reactivity to it;</li>\n<li>configure routing for our Svelte app; and,</li>\n<li>setup protected routes for authenticated users.</li>\n</ul>\n<p>You'll also learn how to consume REST APIs in a Svelte app using Fetch API and update user information in your Svelte store.</p>\n<h2 id=\"what-is-svelte\" style=\"position:relative;\"><a href=\"#what-is-svelte\" aria-label=\"what is svelte permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Svelte?</h2>\n<p><a href=\"https://svelte.dev/\">Svelte</a> is a lightweight and minimal JavaScript compiler that ships a single JavaScript bundle to your application without any internal code of its own. This results in smaller bundle size and often a faster running application. It was also the <a href=\"https://insights.stackoverflow.com/survey/2021#section-most-loved-dreaded-and-wanted-web-frameworks\">most loved framework of 2021</a>.</p>\n<p>But what's the first feature you'd add in a Svelte application? Authentication! It's the gateway for your users to interact and use your website.</p>\n<p>So in this post, I’ll talk about how to add authentication in a Svelte application.</p>\n<h2 id=\"svelte-project-demo\" style=\"position:relative;\"><a href=\"#svelte-project-demo\" aria-label=\"svelte project demo permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Svelte Project Demo</h2>\n<p>You'll learn how to create forms in Svelte and add reactivity to it. You'll also understand how to conditionally render different UI components and set up protected routes for authenticated users in a Svelte application.</p>\n<p>To speed things up, you won't build your own authentication services from scratch. Instead, you'll use <a href=\"https://accounts.loginradius.com/auth.aspx?plan=developer&#x26;action=register\">LoginRadius</a> to quickly configure an authentication backend for your Svelte App.</p>\n<p>Here's a little demo of what your Svelte App would look like by the end of the tutorial:</p>\n<p><video controls width=\"700\" align=\"center\" src=\"/648a1d1a74555638a162015f5d7769b5/Svelte-Auth-LoginRadius-Demo.mp4\"/> </video></p>\n<p>Looks exciting? Let's jump right into it!</p>\n<h2 id=\"setup-a-svelte-app\" style=\"position:relative;\"><a href=\"#setup-a-svelte-app\" aria-label=\"setup a svelte app permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Setup a Svelte App</h2>\n<p>Let's start by creating a new Svelte project and adding some boilerplate code.</p>\n<h3 id=\"create-a-new-svelte-project\" style=\"position:relative;\"><a href=\"#create-a-new-svelte-project\" aria-label=\"create a new svelte project permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create a New Svelte Project</h3>\n<p>Navigate into the directory of your choice and create a new Svelte project by running:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npx degit sveltejs/template svelte-auth-app</span></code></pre>\n<p>That should create a new Svelte project with a simple starter template.</p>\n<p>Additionally, you'll need to install <a href=\"https://github.com/mefechoel/svelte-navigator\">svelte-navigator</a> package to set up routing in your Svelte app:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm i svelte-navigator</span></code></pre>\n<h3 id=\"configure-environment-variable-support\" style=\"position:relative;\"><a href=\"#configure-environment-variable-support\" aria-label=\"configure environment variable support permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configure Environment Variable Support</h3>\n<p>You need to add environment variable support in your Svelte app to store and use your LoginRadius API Keys and Secrets.</p>\n<p>First, install a package called <a href=\"https://www.npmjs.com/package/dotenv\">dotenv</a> that let's create and use a special <code>.env</code> file to define your environment variables.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm i dotenv</span></code></pre>\n<p>Next, head over to the <code>rollup.config.js</code> file. Here, make some configurational changes on the <code>plugins</code> property, so your Svelte app can read those environment variables on the client-side:</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=\"mtk1\">\t...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\tplugins: [</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk11\">replace</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t</span><span class=\"mtk3\">// stringify the object</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t</span><span class=\"mtk12\">__myapp:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t  </span><span class=\"mtk12\">env:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t\t</span><span class=\"mtk12\">isProd:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">production</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t\t...</span><span class=\"mtk11\">config</span><span class=\"mtk1\">().</span><span class=\"mtk12\">parsed</span><span class=\"mtk1\"> </span><span class=\"mtk3\">// attached the .env config</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t}),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t  }),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t],</span></span></code></pre>\n<p>You can refer to the complete <code>rollup.config.js</code> file for this project <a href=\"https://github.com/LoginRadius/engineering-blog-samples/blob/master/Svelte/SvelteAuthApp/rollup.config.js\">here</a>.</p>\n<h3 id=\"create-files-and-folders\" style=\"position:relative;\"><a href=\"#create-files-and-folders\" aria-label=\"create files and folders permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Files and Folders</h3>\n<p>Besides the initial set of files, your project will have the following directory structure:</p>\n<p><img src=\"/7ff6a22848efd6f0ca45f4ef24257176/Directory-Structure-Svelte-App.webp\" alt=\"Directory Structure Svelte App\"></p>\n<p>So go ahead and create those files and folders accordingly. I'll talk about each of these as you start filling them with some code.</p>\n<h3 id=\"add-project-styles\" style=\"position:relative;\"><a href=\"#add-project-styles\" aria-label=\"add project styles permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Add Project Styles</h3>\n<p>Your starter template should come with the following styles inside your <code>App.svelte file</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"css\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk6\">main</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">text-align</span><span class=\"mtk1\">: </span><span class=\"mtk8\">center</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">padding</span><span class=\"mtk1\">: </span><span class=\"mtk7\">1em</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">max-width</span><span class=\"mtk1\">: </span><span class=\"mtk7\">240px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">margin</span><span class=\"mtk1\">: </span><span class=\"mtk7\">0</span><span class=\"mtk1\"> </span><span class=\"mtk8\">auto</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=\"mtk6\">h1</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">color</span><span class=\"mtk1\">: </span><span class=\"mtk8\">#ff3e00</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">text-transform</span><span class=\"mtk1\">: </span><span class=\"mtk8\">uppercase</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">font-size</span><span class=\"mtk1\">: </span><span class=\"mtk7\">4em</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">font-weight</span><span class=\"mtk1\">: </span><span class=\"mtk7\">100</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\">@media</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">min-width</span><span class=\"mtk1\">: </span><span class=\"mtk7\">640px</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk6\">main</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">max-width</span><span class=\"mtk1\">: </span><span class=\"mtk8\">none</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>However, I have also added some additional styles inside the global stylesheet inside the <code>/public/build/global.css</code> file. You can copy those styles from <a href=\"https://github.com/LoginRadius/engineering-blog-samples/blob/master/Svelte/SvelteAuthApp/public/global.css\">here</a>.</p>\n<h2 id=\"global-data-store-for-authenticated-user\" style=\"position:relative;\"><a href=\"#global-data-store-for-authenticated-user\" aria-label=\"global data store for authenticated 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>Global Data Store for Authenticated User</h2>\n<p>Your Svelte app will store the authenticated user's data in a global data store to easily access and modify that data from any component within your application. Svelte provides you with the <code>writable</code> function inside the <code>svelte/store</code> dependency.</p>\n<p>Create a global object called <code>user</code> inside your <code>/src/stores.js</code> file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">writable</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;svelte/store&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">writable</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">localStorage</span><span class=\"mtk1\">.</span><span class=\"mtk12\">user</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\">localStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;user&quot;</span><span class=\"mtk1\">)) : </span><span class=\"mtk4\">null</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">)</span></span></code></pre>\n<p>You have also synced the above <code>user</code> object with the browser's local storage so that this data persists on page reloads. If you're unfamiliar with what local storage is, <a href=\"https://www.loginradius.com/blog/engineering/guest-post/local-storage-vs-session-storage-vs-cookies/\">check out my guide on Local Storage vs. Session Storage vs. Cookies</a> that dives deeper into browser storage and other related concepts.</p>\n<h2 id=\"the-app-component-boilerplate\" style=\"position:relative;\"><a href=\"#the-app-component-boilerplate\" aria-label=\"the app component boilerplate permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 App Component Boilerplate</h2>\n<p>The root component in your Svelte app is the App Component. This is located inside <code>/src/App.svelte</code>.</p>\n<p>It has the following imports declared inside:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  /** IMPORTS */ import Login from &#39;./Login.svelte&#39;; import Signup from</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  &#39;./Signup.svelte&#39;; import Home from &#39;./Home.svelte&#39;; import PrivateRoute from</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  &quot;./routes/PrivateRoutes.svelte&quot;; /** VARIABLES */ const sdkoptions = </span><span class=\"mtk4\">{}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>It also has an <code>sdkoptions</code> variable that will store the environment variables that you can easily pass to different components as and when they need it. You can get rid of any additional HTML inside the <code>App.svelte</code> file generated by the starter template.</p>\n<h2 id=\"the-login-component\" style=\"position:relative;\"><a href=\"#the-login-component\" aria-label=\"the login component permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Login Component</h2>\n<p>Let's head over to the <code>/src/Login.svelte</code> file to create the Login Page.</p>\n<h3 id=\"create-login-form\" style=\"position:relative;\"><a href=\"#create-login-form\" aria-label=\"create login form permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create Login Form</h3>\n<p>Here's what the HTML of your Login Form consists of:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h3</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Login</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h3</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">form</span><span class=\"mtk1\"> </span><span class=\"mtk14\">on:submit|preventDefault=&quot;{handleSubmit}&quot;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk14\">&lt;input</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;form-field&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">bind</span><span class=\"mtk1\">:</span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;{email}&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;email&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Email&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;form-field&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">bind</span><span class=\"mtk1\">:</span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;{password}&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Password&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;form-field&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    Login</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">&lt;/</span><span class=\"mtk12\">form</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  Don&#39;t have an account?</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">strong</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;link&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">on</span><span class=\"mtk1\">:</span><span class=\"mtk12\">click</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;{navigateToSignup}&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Sign up</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">strong</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>You have a login form with two input fields for email and password and a submit button. The form also has an <code>on:submit</code> handler with an event modifier to prevent the default reloading action of the form when it gets submitted.</p>\n<p>After the form, you have a simple link with an <code>on:click</code> handler that allows the user to navigate to the Signup page.</p>\n<h3 id=\"login-form-field-bindings-and-handlers\" style=\"position:relative;\"><a href=\"#login-form-field-bindings-and-handlers\" aria-label=\"login form field bindings and handlers permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Login Form Field Bindings and Handlers</h3>\n<p>Inside the script of your Login component, create two variables — <code>email</code> and <code>password</code> — to handle the bindings to the input fields. Also, make the <code>sdkoptions</code> variable exportable since you'll receive it as <code>props</code> from the App component.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">let email; let password; export let sdkoptions;</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>You also need to create a function called <code>handleSubmit</code> that is the <code>on:submit</code> handler for your Login form:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    const handleSubmit=(e)=&gt;</span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span><span class=\"mtk12\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">loginFields</span><span class=\"mtk1\">={</span><span class=\"mtk12\">email</span><span class=\"mtk1\">,</span><span class=\"mtk12\">password</span><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t   </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">loginFields</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    const navigateToSignup=()=&gt;</span><span class=\"mtk4\">{}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>At the moment, you're simply encapsulating the <code>email</code> and <code>password</code> bindings into a JavaScript object. Later, you'll send a request to your Login API here. You also have an empty <code>navigateToSignup</code> function that I'll come back to once you set up your routes.</p>\n<p>Let's render the Login component inside your <code>App.svelte</code> file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">main</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Login</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">main</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p><img src=\"/7804c05118f523c534443446c37d8939/Login-Page.webp\" alt=\"Login Page\"></p>\n<p>Awesome! Let's follow the same process to create your Signup form.</p>\n<h2 id=\"the-signup-component\" style=\"position:relative;\"><a href=\"#the-signup-component\" aria-label=\"the signup component permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Signup Component</h2>\n<p>Head over to the <code>/src/Signup.svelte</code> file to create your Signup Page.</p>\n<h3 id=\"create-signup-form\" style=\"position:relative;\"><a href=\"#create-signup-form\" aria-label=\"create signup form permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create Signup Form</h3>\n<p>Similar to the Login Form, the Signup Form will have the following HTML:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h3</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Create a New Account</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h3</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">form</span><span class=\"mtk1\"> </span><span class=\"mtk14\">on:submit|preventDefault=&quot;{handleSubmit}&quot;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk14\">&lt;input</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;form-field&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">bind</span><span class=\"mtk1\">:</span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;{firstName}&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;text&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;First Name&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;form-field&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">bind</span><span class=\"mtk1\">:</span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;{lastName}&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;text&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Last Name&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;form-field&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">bind</span><span class=\"mtk1\">:</span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;{email}&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;email&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Email&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;form-field&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">bind</span><span class=\"mtk1\">:</span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;{password}&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Password&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;form-field&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    Signup</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">&lt;/</span><span class=\"mtk12\">form</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  Already have an account?</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">strong</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;link&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">on</span><span class=\"mtk1\">:</span><span class=\"mtk12\">click</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;{navigateToLogin}&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Login</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">strong</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>The only difference is now you have two additional fields — first name and last name. You also have a link just below the signup form that takes the user to the login page.</p>\n<h3 id=\"signup-form-field-bindings-and-handlers\" style=\"position:relative;\"><a href=\"#signup-form-field-bindings-and-handlers\" aria-label=\"signup form field bindings and handlers permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Signup Form Field Bindings and Handlers</h3>\n<p>Here's what the script section of your <code>Signup.svelte</code> file should look like:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"12\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\tlet email;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let password;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let firstName;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let lastName;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let loading;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    export let sdkoptions;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    const handleSubmit=()=&gt;</span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">signupFields</span><span class=\"mtk1\">={</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;FirstName&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">firstName</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;LastName&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lastName</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;Email&quot;</span><span class=\"mtk12\">:</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=\"mtk8\">&quot;Type&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Primary&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;Value&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">email</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=\"mtk8\">&quot;Password&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">password</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">signupFields</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   const navigateToLogin=()=&gt;</span><span class=\"mtk4\">{}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>Your <code>signupFields</code> object has a specific format because it aligns with the structure of your Signup API's request. It would make complete sense when you hook your Signup API here.</p>\n<p>Let's render the Signup component inside your <code>App.svelte</code> file:</p>\n<p><img src=\"/a18f23d4ceb0fe893dd8d49789a5b911/Signup-Page.webp\" alt=\"Signup Page\"></p>\n<h2 id=\"the-home-component\" style=\"position:relative;\"><a href=\"#the-home-component\" aria-label=\"the home component permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Home Component</h2>\n<p>Let's create your Home component or the page where you'll redirect an user on a successfull login. Inside <code>/src/Home.svelte</code> file, add the following HTML:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"13\"><code class=\"grvsc-code\"><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\">_user</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h3</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Welcome </span><span class=\"mtk4\">{</span><span class=\"mtk12\">_user</span><span class=\"mtk1\">?.</span><span class=\"mtk12\">profile</span><span class=\"mtk1\">?.</span><span class=\"mtk12\">FullName</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h3</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">on</span><span class=\"mtk1\">:</span><span class=\"mtk12\">click</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;{logout}&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Logout</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{/</span><span class=\"mtk15\">if</span><span class=\"mtk1\">}</span></span></code></pre>\n<p>In the above HTML, you simply use some Svelte conditionals to render the user's name and a logout button. The script part of your Home component looks like this:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"14\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    import </span><span class=\"mtk4\">{</span><span class=\"mtk12\">user</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> from &#39;./stores&#39;;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let _user;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    user.subscribe(data=&gt;_user=data)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    const logout=()=&gt;</span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk11\">set</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 class=\"mtk12\">localStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">clear</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>You import the global <code>user</code> object from your Svelte store and store it inside your Home component's state <code>_user</code>. For the <code>logout</code> function, you simply set this <code>user</code> object in your store to null and clear the local storage.</p>\n<h2 id=\"setup-loginradius\" style=\"position:relative;\"><a href=\"#setup-loginradius\" aria-label=\"setup 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>Setup LoginRadius</h2>\n<p>The next step is to set up LoginRadius, so you can start using its Authentication APIs from your Svelte App.</p>\n<h3 id=\"create-loginradius-account\" style=\"position:relative;\"><a href=\"#create-loginradius-account\" aria-label=\"create loginradius account permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create LoginRadius Account</h3>\n<p>Head over to <a href=\"https://accounts.loginradius.com/auth.aspx?plan=developer&#x26;action=register\">LoginRadius</a> and create a new account by filling in the following details:</p>\n<p><img src=\"/07e3f97860f329f52e8fd676c7ca73fb/Signup-2.webp\" alt=\"Signup 2\"></p>\n<p>You'll then see a form with the name of your App, a URL, and a Data Center:</p>\n<p><img src=\"/fdeb64de0e13dcf68954b8d6a8c801b5/Signup-3.webp\" alt=\"Signup 3\"></p>\n<p>Hit <strong>Next</strong> and LoginRadius will set up an authentication app for you. You can try the pre-built authentication page LoginRadius provides for your app by clicking on <strong>Try Signing Up Now</strong>.</p>\n<p><img src=\"/a7d6dc1dd6df5add1461011a1a270cb3/Signup-4.webp\" alt=\"Signup 4\"></p>\n<p>Once you do that, you'll be shown a pre-built authentication page of your LoginRadius app:</p>\n<p><img src=\"/54605addc29f464b1e42e5e254d71222/LoginRadius-Auth-Page.webp\" alt=\"LoginRadius Auth Page\"></p>\n<p>However, for this tutorial, all you need are the LoginRadius APIs since you already have a frontend (your Svelte App) in place.</p>\n<h3 id=\"get-loginradius-api-configurations\" style=\"position:relative;\"><a href=\"#get-loginradius-api-configurations\" aria-label=\"get loginradius api configurations permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Get LoginRadius API Configurations</h3>\n<p>Once you're inside your LoginRadius account, head over to the <strong>Configurations</strong> tab from your dashboard. Then expand the <strong>API Credentials</strong> tab of your application.</p>\n<p><img src=\"/33760eee3a762ea61cb29f2f95e3bdfe/LoginRadius-Configuration-Tab.webp\" alt=\"LoginRadius Configuration Tab\"></p>\n<p>Inside that, you should see your APP Name, API Key, and API Secret.</p>\n<p><img src=\"/9a345c5c29b7bf85649af7394a806147/LoginRadius-API-Credentials.webp\" alt=\"LoginRadius API Credentials\"></p>\n<h3 id=\"add-api-credentials-as-environment-variables\" style=\"position:relative;\"><a href=\"#add-api-credentials-as-environment-variables\" aria-label=\"add api credentials as environment variables permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Add API Credentials as Environment Variables</h3>\n<p>Head back to the Svelte App's <code>.env</code> file and add the above credentials inside it:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"15\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">APP_NAME=&lt;YOUR_APP_NAME&gt;</span>\n<span class=\"grvsc-line\">API_CLIENT_KEY= &lt;YOUR_APP_API_KEY&gt;</span>\n<span class=\"grvsc-line\">API_SECRET= &lt;YOUR_APP_API_SECRET&gt;</span></code></pre>\n<p>You'll need to ensure that the above <code>.env</code> file is present inside the <code>.gitignore</code> of your Svelte project. You don't want to accidentally push this file to a public repository on Github.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"16\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">/node_modules/</span>\n<span class=\"grvsc-line\">/public/build/</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">.DS_Store</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">.env</span></code></pre>\n<h3 id=\"consume-environment-variables-in-svelte-components\" style=\"position:relative;\"><a href=\"#consume-environment-variables-in-svelte-components\" aria-label=\"consume environment variables in svelte components permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Consume Environment Variables in Svelte Components</h3>\n<p>Finally, you need to extract these environment variables in your <code>sdkoptions</code> variables inside your App component file.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"17\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk8\">&quot;apiKey&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">__myapp</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&quot;env&quot;</span><span class=\"mtk1\">].</span><span class=\"mtk12\">API_CLIENT_KEY</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk8\">&quot;appName&quot;</span><span class=\"mtk12\">:__myapp</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&quot;env&quot;</span><span class=\"mtk1\">].</span><span class=\"mtk12\">APP_NAME</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&quot;apiSecret&quot;</span><span class=\"mtk12\">:__myapp</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&quot;env&quot;</span><span class=\"mtk1\">].</span><span class=\"mtk12\">API_SECRET</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span></code></pre>\n<p>And pass this variable as props to both the Login and Signup component:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"18\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Login</span><span class=\"mtk1\"> </span><span class=\"mtk4\">{</span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Signup</span><span class=\"mtk1\"> </span><span class=\"mtk4\">{</span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span></code></pre>\n<p>Great! Now you're ready to integrate LoginRadius APIs in your Svelte app.</p>\n<h2 id=\"integrate-loginradius-api\" style=\"position:relative;\"><a href=\"#integrate-loginradius-api\" aria-label=\"integrate loginradius 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>Integrate LoginRadius API</h2>\n<p>You'll use two APIs — one for registering the user on the Signup page and the other for authenticating the user on the Login Page. However, both APIs will take the API key and API secret as query parameters.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"19\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">endpoint</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">`</span><span class=\"mtk4\">${</span><span class=\"mtk12\">BASE_URL</span><span class=\"mtk4\">}</span><span class=\"mtk8\">?apikey=</span><span class=\"mtk4\">${</span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">apiKey</span><span class=\"mtk4\">}</span><span class=\"mtk8\">&apisecret=</span><span class=\"mtk4\">${</span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">apiSecret</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span></span></code></pre>\n<p>So in the above endpoint, you'll only change the <code>BASE_URL</code> according to which API you're hitting.</p>\n<h3 id=\"integrate-signup-api\" style=\"position:relative;\"><a href=\"#integrate-signup-api\" aria-label=\"integrate signup 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>Integrate Signup API</h3>\n<p>Inside your <code>Signup.svelte</code> file, you'll create a variable called <code>signupResponse</code> to store the result of the Signup API. It also has properties like <code>success</code> and <code>error</code> to prompt the user on the status of your API calls.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"20\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let signupResponse=</span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">success</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 class=\"mtk12\">error</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 class=\"mtk12\">uid</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 class=\"mtk12\">id</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 class=\"mtk12\">fullname</span><span class=\"mtk1\">:</span><span class=\"mtk4\">null</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> \tlet loading;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>Since an API request is an asynchronous process, you also have a' loading' variable to disable the submit button until the API responds.</p>\n<h4 id=\"signup-api-request-on-signup-form-submission\" style=\"position:relative;\"><a href=\"#signup-api-request-on-signup-form-submission\" aria-label=\"signup api request on signup form submission permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Signup API Request on Signup Form Submission</h4>\n<p>You need to send a request to the Signup API inside your <code>handleSubmit()</code> function. First, set the <code>loading</code> to true and reset the <code>signupResponse</code> object. Then, use the fetch API to make a POST request with the <code>signupFields</code> object as post parameter:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"21\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">handleSubmit</span><span class=\"mtk1\"> = () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">signupFields</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">FirstName:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">firstName</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">LastName:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lastName</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">Email:</span><span class=\"mtk1\"> [</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">Type:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Primary&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">Value:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">email</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\">Password:</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">loading</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">true</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">success:</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 class=\"mtk12\">error:</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 class=\"mtk12\">uid:</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 class=\"mtk12\">id:</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 class=\"mtk12\">fullname:</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 class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">endpoint</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">`https://api.loginradius.com/identity/v2/manage/account?apikey=</span><span class=\"mtk4\">${</span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">apiKey</span><span class=\"mtk4\">}</span><span class=\"mtk8\">&apisecret=</span><span class=\"mtk4\">${</span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">apiSecret</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk12\">endpoint</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">method:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;POST&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk8\">&quot;Content-Type&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;application/json&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">body:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">(</span><span class=\"mtk12\">signupFields</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">response</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">())</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</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=\"mtk11\">catch</span><span class=\"mtk1\">(</span><span class=\"mtk12\">error</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">error</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">finally</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">loading</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></code></pre>\n<h4 id=\"handle-api-response\" style=\"position:relative;\"><a href=\"#handle-api-response\" aria-label=\"handle api response permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Handle API Response</h4>\n<p>Inside the callback of your fetch request, you can handle any errors returned by the API based on different error codes. In case of success, you'll populate your <code>signupResponse</code> object with data from the API. In the <code>finally</code> block, set the <code>loading</code> to false.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"22\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">.</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</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\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">ErrorCode</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\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">ErrorCode</span><span class=\"mtk1\">==</span><span class=\"mtk7\">936</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">={</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    ...</span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">error:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Message</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">             }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> </span><span class=\"mtk15\">if</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">ErrorCode</span><span class=\"mtk1\">==</span><span class=\"mtk7\">1134</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">={</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    ...</span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">error:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Errors</span><span class=\"mtk1\">[</span><span class=\"mtk7\">0</span><span class=\"mtk1\">].</span><span class=\"mtk12\">ErrorMessage</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span><span class=\"mtk15\">else</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">={</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    ...</span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">error:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Description</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span><span class=\"mtk15\">else</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">={</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                ...</span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">success:</span><span class=\"mtk8\">&quot;Account created successfully! Please login via the same details.&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">fullname:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">FullName</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">id:data</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\">uid:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Uid</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<h4 id=\"disable-submit-button\" style=\"position:relative;\"><a href=\"#disable-submit-button\" aria-label=\"disable submit button permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Disable Submit Button</h4>\n<p>You can set the disabled attribute on your Submit button based on the loading state of the API.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"23\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">disabled</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;{loading}&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;form-field&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  Signup</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span></code></pre>\n<h4 id=\"show-signup-success-and-error\" style=\"position:relative;\"><a href=\"#show-signup-success-and-error\" aria-label=\"show signup success and error permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Show Signup Success and Error</h4>\n<p>Lastly, render a conditional template based on the status of your Signup API.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"24\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">... {#</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Error ❌ </span><span class=\"mtk4\">{</span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{/</span><span class=\"mtk15\">if</span><span class=\"mtk1\">} {#</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">.</span><span class=\"mtk12\">success</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;success&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  Success ✔ </span><span class=\"mtk4\">{</span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">.</span><span class=\"mtk12\">success</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{/</span><span class=\"mtk15\">if</span><span class=\"mtk1\">} ...</span></span></code></pre>\n<p>And that's it! Let's give your Signup functionality a whirl. Create a new account first:</p>\n<p><img src=\"/d6d0033b0fcf1b74c7ccf39658e1f036/Signup-Success-with-API.webp\" alt=\"Signup Success with API\"></p>\n<p>And voila! You can see in the network tab that the API is successful. And you got back a bunch of data about the newly created user. You also have a success that appears underneath the Signup form.</p>\n<p>Let's also test an erroneous flow. What if you signup via the same credentials again?</p>\n<p><img src=\"/6f7b551dfb5856a6f944dac271fc31fa/Signup-Failure-Existing-Email.webp\" alt=\"Signup Failure Existing Email\"></p>\n<p>The LoginRadius Signup API returns the error message, details, error code, etc., that you've handled accordingly.</p>\n<p>Also, if you use a simple password, the LoginRadius API returns an error based on a validation mechanism.</p>\n<p><img src=\"/40d4723bf56be75f912462de00e42e33/Signup-Error-Password-Validation.webp\" alt=\"Signup Error Password Validation\"></p>\n<p>That's great because it makes your authentication workflow more air-tight.</p>\n<h3 id=\"integrate-login-api\" style=\"position:relative;\"><a href=\"#integrate-login-api\" aria-label=\"integrate login 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>Integrate Login API</h3>\n<p>Similarly, you can now integrate the Login API as well in your <code>Login.svelte</code> file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"25\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    import </span><span class=\"mtk4\">{</span><span class=\"mtk12\">user</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> from &#39;./stores&#39;;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let email;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let password;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let loading;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let loginResponse=</span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">error</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 class=\"mtk12\">success</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 class=\"mtk12\">profile</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 class=\"mtk12\">auth_token</span><span class=\"mtk1\">:</span><span class=\"mtk4\">null</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    export let sdkoptions;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    const handleSubmit=(e)=&gt;</span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span><span class=\"mtk12\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">loginFields</span><span class=\"mtk1\">={</span><span class=\"mtk12\">email</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=\"mtk12\">loading</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\">loginResponse</span><span class=\"mtk1\">={</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">error:</span><span class=\"mtk4\">null</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">success:</span><span class=\"mtk4\">null</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">profile:</span><span class=\"mtk4\">null</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">auth_token:</span><span class=\"mtk4\">null</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span><span class=\"mtk12\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">endpoint</span><span class=\"mtk1\">=</span><span class=\"mtk8\">`https://api.loginradius.com/identity/v2/auth/login?apikey=</span><span class=\"mtk4\">${</span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">apiKey</span><span class=\"mtk4\">}</span><span class=\"mtk8\">&apisecret=</span><span class=\"mtk4\">${</span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">apiSecret</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span><span class=\"mtk12\">loading</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=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk12\">endpoint</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\">method:</span><span class=\"mtk8\">&#39;POST&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&#39;Content-Type&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;application/json&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">body:</span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">(</span><span class=\"mtk12\">loginFields</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }).</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">response</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">())</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</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\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">ErrorCode</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\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">ErrorCode</span><span class=\"mtk1\">==</span><span class=\"mtk7\">936</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">={</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        ...</span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk12\">error:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Message</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> </span><span class=\"mtk15\">if</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">ErrorCode</span><span class=\"mtk1\">==</span><span class=\"mtk7\">1134</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">={</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        ...</span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk12\">error:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Errors</span><span class=\"mtk1\">[</span><span class=\"mtk7\">0</span><span class=\"mtk1\">].</span><span class=\"mtk12\">ErrorMessage</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span><span class=\"mtk15\">else</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">={</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        ...</span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk12\">error:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Description</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span><span class=\"mtk15\">else</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">={</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    ...</span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">success:</span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">profile:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Profile</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">auth_token:</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk12\">access_token:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">access_token</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk12\">refresh_token:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">refresh_token</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk12\">ttl:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">expires_in</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\">user</span><span class=\"mtk1\">.</span><span class=\"mtk11\">set</span><span class=\"mtk1\">(</span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">localStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;user&#39;</span><span class=\"mtk1\">,</span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">(</span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">catch</span><span class=\"mtk1\">(</span><span class=\"mtk12\">error</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">error</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">finally</span><span class=\"mtk1\">(()</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk12\">loading</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=\"mtk4\">}</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=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{#</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Error ❌ </span><span class=\"mtk4\">{</span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{/</span><span class=\"mtk15\">if</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{#</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">.</span><span class=\"mtk12\">success</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;success&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        Success ✔</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{/</span><span class=\"mtk15\">if</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    Don&#39;t have an account?</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">strong</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;link&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">on</span><span class=\"mtk1\">:</span><span class=\"mtk12\">click</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">navigateToSignup</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Sign up</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">strong</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>If you relate it to the Signup component, it's almost identical. The only thing that has changed is the API endpoint. Additionally, if the Login API is a success, you're also storing the data in your <code>user</code> store and consequently updating your <code>localStorage</code>.</p>\n<p>Let's also test this out:</p>\n<p><img src=\"/431c32e3326ed149d1fccfa746e5829a/Login-API-Success.webp\" alt=\"Login API Success\"></p>\n<p>Let's also test an erroneous Login flow by entering the credentials for a user that doesn't exist:</p>\n<p><img src=\"/df37014cbbe64aa85cd395d049a791fa/Login-Error.webp\" alt=\"Login Error\"></p>\n<p>Great! Let's now tie all these individual pages together by setting up routing in your Svelte app.</p>\n<h2 id=\"setup-routes\" style=\"position:relative;\"><a href=\"#setup-routes\" aria-label=\"setup 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>Setup Routes</h2>\n<p>You'll use the <code>svelte-navigator</code> package that you previously installed to configure routing in your app.</p>\n<h3 id=\"add-routing\" style=\"position:relative;\"><a href=\"#add-routing\" aria-label=\"add routing permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Add Routing</h3>\n<p>First, you'll define the routes for the Signup, Login, and Home pages inside your <code>App.svelte</code> file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"26\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  /** IMPORTS */</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  import </span><span class=\"mtk4\">{</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Router</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Route</span><span class=\"mtk1\"> </span><span class=\"mtk4\">}</span><span class=\"mtk1\"> from &quot;svelte-navigator&quot;;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">main</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Router</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Route</span><span class=\"mtk1\"> </span><span class=\"mtk12\">path</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;signup&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Signup</span><span class=\"mtk1\"> </span><span class=\"mtk4\">{</span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Route</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Route</span><span class=\"mtk1\"> </span><span class=\"mtk12\">path</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;login&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Login</span><span class=\"mtk1\"> </span><span class=\"mtk4\">{</span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Route</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Route</span><span class=\"mtk1\"> </span><span class=\"mtk12\">path</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Home</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Route</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Router</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">main</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>If you visit <code>/login</code>, you should see the Login Page. Similarly, if you go to <code>/signup</code>, you should see the Signup Page.</p>\n<h3 id=\"programmatic-redirection\" style=\"position:relative;\"><a href=\"#programmatic-redirection\" aria-label=\"programmatic redirection permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Programmatic Redirection</h3>\n<p>Remember, you had a link to the Signup page at the bottom of the Login page and vice versa?</p>\n<p>Also, your login page doesn't redirect anywhere after you login successfully. In order to programmatically navigate to a specific page on completion of an action, you can use the <code>useNavigate</code> hook from the <code>svelte-navigator</code> library.</p>\n<p>To use this hook, import <code>useNavigate</code> and save its invoked reference inside a variable, as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"27\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  import </span><span class=\"mtk4\">{</span><span class=\"mtk12\">useNavigate</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> from &quot;svelte-navigator&quot;; const navigate = useNavigate();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>Now call the <code>navigate()</code> function and pass the path of the page you wish to redirect to. So let's complete the <code>navigateToLogin</code> function inside your Signup component:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"28\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">... const navigateToLogin=()=&gt;navigate(&#39;/login&#39;); ...</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>Similarly, you can also complete the <code>navigateToSignup</code> function inside your Login component:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"29\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">... const navigateToSignup=()=&gt;navigate(&#39;/signup&#39;) ...</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>Finally, you'll also navigate to the Home page on a successful response from your Login API inside your Login component's <code>handleSubmit</code> function:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"30\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">handleSubmit</span><span class=\"mtk1\">=(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk12\">endpoint</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> \t\t\t\t...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span><span class=\"mtk12\">else</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t\t...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk11\">navigate</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">&lt;/</span><span class=\"mtk12\">script</span><span class=\"mtk1\">&gt;</span></span></code></pre>\n<p>Great! You can now navigate from your Login page to the Signup page and vice versa. You should also be automatically redirected to the Home page on a successful login.</p>\n<h3 id=\"add-protectedprivate-routes\" style=\"position:relative;\"><a href=\"#add-protectedprivate-routes\" aria-label=\"add protectedprivate 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>Add Protected/Private Routes</h3>\n<p>If you try to visit the Home component by entering the path <code>/</code> in the URL, you'll be able to see the Home page regardless of your authenticated state. However, you must protect this route so that it's only accessible to authenticated users in your application.</p>\n<p>For this purpose, you have created a <code>RouteGuard.svelte</code> file inside your <code>routes</code> folder. It's a higher-order component that uses the <code>useNavigation</code> hook to programmatically redirect to the login page if an unauthenticated user visits the home page. You use the <code>user</code> object from your Svelte store to validate the authenticated state of a user.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"31\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    import </span><span class=\"mtk4\">{</span><span class=\"mtk1\"> </span><span class=\"mtk12\">useNavigate</span><span class=\"mtk1\">, </span><span class=\"mtk12\">useLocation</span><span class=\"mtk1\"> </span><span class=\"mtk4\">}</span><span class=\"mtk1\"> from &quot;svelte-navigator&quot;;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    import </span><span class=\"mtk4\">{</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> </span><span class=\"mtk4\">}</span><span class=\"mtk1\"> from &quot;../stores&quot;;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    const navigate = useNavigate();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    const location = useLocation();</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    $: if (!$user) </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">navigate</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">state:</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">from:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">$location</span><span class=\"mtk1\">.</span><span class=\"mtk12\">pathname</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">replace:</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=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\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=\"mtk17\">&lt;</span><span class=\"mtk4\">slot</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  {/</span><span class=\"mtk15\">if</span><span class=\"mtk1\">}</span></span></code></pre>\n<p>You can then wrap another higher order Route component on top of the <code>RouteGuard</code> component inside the <code>PrivateRoutes.svelte</code> file, as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"32\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    import </span><span class=\"mtk4\">{</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Route</span><span class=\"mtk1\"> </span><span class=\"mtk4\">}</span><span class=\"mtk1\"> from &quot;svelte-navigator&quot;;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    import RouteGuard from &quot;./RouteGuard.svelte&quot;;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    export let path;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Route</span><span class=\"mtk1\"> </span><span class=\"mtk4\">{</span><span class=\"mtk12\">path</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk12\">let</span><span class=\"mtk1\">:</span><span class=\"mtk12\">params</span><span class=\"mtk1\"> </span><span class=\"mtk12\">let</span><span class=\"mtk1\">:</span><span class=\"mtk12\">location</span><span class=\"mtk1\"> </span><span class=\"mtk12\">let</span><span class=\"mtk1\">:</span><span class=\"mtk12\">navigate</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">RouteGuard</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">slot</span><span class=\"mtk1\"> </span><span class=\"mtk4\">{</span><span class=\"mtk12\">params</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk4\">{</span><span class=\"mtk12\">location</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk4\">{</span><span class=\"mtk12\">navigate</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">RouteGuard</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Route</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>Now, all you need to do is use this <code>PrivateRoute</code> component to wrap your Home component instead of a regular Route component:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"33\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">PrivateRoute</span><span class=\"mtk1\"> </span><span class=\"mtk12\">path</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">let</span><span class=\"mtk1\">:</span><span class=\"mtk12\">location</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Home</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">PrivateRoute</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span></code></pre>\n<p>And now you should be able to access the <code>/</code> route or the Home page only when you're authenticated:</p>\n<p><img src=\"/0b7bfdfedf02190c8f4cf508c3d5ae7d/Home-Component.webp\" alt=\"Home Component\"></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>I hope I've shed some light on how to authenticate Svelte apps. You can do a lot from here, like adding <a href=\"https://kit.svelte.dev/\">Svelte Kit</a> to this project to simplify the routing system for your Svelte application.</p>\n<p>You can <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/Svelte/SvelteAuthApp\">refer to the entire source code for this tutorial here</a>.</p>\n<p>You can also explore <a href=\"https://accounts.loginradius.com/auth.aspx?plan=developer&#x26;action=register\">LoginRadius</a> to add forgot password functionality or social signups with Facebook and Google.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk6 { color: #D7BA7D; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk17 { color: #808080; }\n  .dark-default-dark .mtk14 { color: #F44747; }\n</style>","frontmatter":{"date":"March 10, 2022","updated_date":null,"description":"Are you building Svelte apps? In this tutorial, you'll learn to add secure user authentication in your Svelte apps using LoginRadius APIs.","title":"How to Authenticate Svelte Apps","tags":["Authentication","Svelte","LoginRadius"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/c47b7b41ce6f525c5d8fa037d7313ae0/58556/authenticate-svelte-apps.webp","srcSet":"/static/c47b7b41ce6f525c5d8fa037d7313ae0/61e93/authenticate-svelte-apps.webp 200w,\n/static/c47b7b41ce6f525c5d8fa037d7313ae0/1f5c5/authenticate-svelte-apps.webp 400w,\n/static/c47b7b41ce6f525c5d8fa037d7313ae0/58556/authenticate-svelte-apps.webp 800w,\n/static/c47b7b41ce6f525c5d8fa037d7313ae0/99238/authenticate-svelte-apps.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Siddhant Varma","github":"FuzzySid","avatar":null}}}},{"node":{"excerpt":"Github is great, as you may already know. But, did you ever think to make your profile attractive for potential employers, followers…","fields":{"slug":"/engineering/build-your-github-profile/"},"html":"<p>Github is great, as you may already know.</p>\n<p>But, did you ever think to make your profile attractive for potential employers, followers, recruiters, and visitors?</p>\n<p>Let's make a better version of it.</p>\n<h2 id=\"github-profile-image-frame\" style=\"position:relative;\"><a href=\"#github-profile-image-frame\" aria-label=\"github profile image frame permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Github Profile Image Frame</h2>\n<p>It's up to you to decide how you want this frame — photo-less, cartoon avatar, or best explaining image.</p>\n<p>For the best image, take a quality click; quality means not blurred, perfect lighting, and good posture.\nIf someone looks at the photo, it shall explain your personality.</p>\n<h2 id=\"github-profile-page\" style=\"position:relative;\"><a href=\"#github-profile-page\" aria-label=\"github profile page permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Github Profile Page</h2>\n<p>Github has a <a href=\"https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-profile/customizing-your-profile/managing-your-profile-readme\">feature called README</a> if you do not know already.</p>\n<p>Check out some listing of <a href=\"https://github.com/abhisheknaiidu/awesome-github-profile-readme\">awesome GitHub profiles</a>.</p>\n<p>To start this, first, you need to create a project that is the same as your GitHub username.</p>\n<p><strong>Example:</strong> My user name is <code>abhir9</code>, and I need to create a repo with the same name <code>abhir9</code> with a <code>README.md</code> file.</p>\n<p>This <code>README.me</code> will act as the profile page: <a href=\"https://github.com/abhir9\">abhir9</a></p>\n<p>It is the actual README file created using a repo with my GitHub username: <a href=\"https://github.com/abhir9/abhir9/blob/main/README.md\">abhir9</a></p>\n<p>Here you can add your quotes, hello statement, greetings, etc. It is connected to the viewer on your behalf.</p>\n<p>So write a short paragraph or a brief story to introduce yourself.</p>\n<p>There are some apps from contributors that extract the information based on your profile name and share stats and charts.</p>\n<ul>\n<li><a href=\"https://github-readme-stats.vercel.app\">github readme stats</a>\ne.g.: <code>https://github-readme-stats.vercel.app/api?username=abhir9&#x26;show_icons=true&#x26;count_private=true&#x26;theme=react</code></li>\n<li><a href=\"https://readme-typing-svg.herokuapp.com\">readme typing svg</a>\ne.g.: <code>https://readme-typing-svg.herokuapp.com?size=50&#x26;center=true&#x26;vCenter=true&#x26;width=800&#x26;height=100&#x26;lines=Namaste%20%F0%9F%99%8F%3BPranam%20%F0%9F%99%8F%3BKhamma%20Ghani%20%F0%9F%99%8F%3BVanakkam%20%F0%9F%99%8F%3BSat%20Sri%20Akaal%20%F0%9F%99%8F%3BAssalam%20Alaikum%20%F0%9F%99%8F%3B</code></li>\n<li><a href=\"https://views.whatilearened.today\">whatilearened</a>\ne.g.: <code>https://views.whatilearened.today/views/github/abhir9/abhir9.webp?cache=remove</code></li>\n<li><a href=\"https://github-readme-streak-stats.herokuapp.com\">github readme streak stats</a>\ne.g.: <code>https://github-readme-streak-stats.herokuapp.com/?user=abhir9&#x26;theme=react</code></li>\n<li>SVG Icons\ne.g.: <code>https://raw.githubusercontent.com/devicons/devicon/master/icons/ubuntu/ubuntu-plain.webp</code></li>\n</ul>\n<p>Many other online apps can be used per your need — e.g., how you want to decorate your profile page.</p>\n<h2 id=\"github-pinned-repos\" style=\"position:relative;\"><a href=\"#github-pinned-repos\" aria-label=\"github pinned repos permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Github Pinned Repos</h2>\n<p>Github allows you to pin up to 6 repos.</p>\n<p>Try to pin the best of your projects' repos. Mostly, people do visit these repos if they land on your profiles.</p>\n<h2 id=\"greeny-contributions\" style=\"position:relative;\"><a href=\"#greeny-contributions\" aria-label=\"greeny contributions permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Greeny Contributions</h2>\n<p>There is a heat map that represents your contributions.</p>\n<p>Heat map graph will automatically generate as per your contributions. Try to keep it greener by contributing usefully to your favorite projects.</p>\n<h2 id=\"readme-for-every-project\" style=\"position:relative;\"><a href=\"#readme-for-every-project\" aria-label=\"readme for every project permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>README for Every Project</h2>\n<p>Whether it's a minor or significant project, add a well-descriptive README file. It helps anyone clearly understand what your project does and how they can contribute if they want to.</p>\n<p>Format it in a better way; if you don't know very much about Markdown format, you can use an online tool like <a href=\"https://pandao.github.io/editor.md/en.html\">Pandao</a></p>\n<p>You can use images, screenshots, gifs, resources list, contribution guidelines, license, etc.</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 28, 2022","updated_date":null,"description":"Your GitHub profile is vital in showcasing your programming skills. Learn how you can leverage GitHub profile to showcase your skills and expertise.","title":"How to Build Your Github Profile","tags":["Github"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/9538f6a4bb1b02fa3b5daf9e83f0e026/58556/index.webp","srcSet":"/static/9538f6a4bb1b02fa3b5daf9e83f0e026/61e93/index.webp 200w,\n/static/9538f6a4bb1b02fa3b5daf9e83f0e026/1f5c5/index.webp 400w,\n/static/9538f6a4bb1b02fa3b5daf9e83f0e026/58556/index.webp 800w,\n/static/9538f6a4bb1b02fa3b5daf9e83f0e026/99238/index.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Abhimanyu Singh Rathore","github":"abhir9","avatar":null}}}},{"node":{"excerpt":"As human interactions become more and more digitalized, your business and personal websites have become far more important than a couple of…","fields":{"slug":"/engineering/importance-of-search-functionality-for-websites/"},"html":"<p>As human interactions become more and more digitalized, your business and personal websites have become far more important than a couple of decades ago.</p>\n<p>When a user lands on your website, it's essential to help the user find the right information as effectively as possible. Otherwise, the user may leave the website, losing potential business opportunities or visibility.</p>\n<p>One of the important ways to improve website design and help users find the information they want is to make the site searchable using the search functionality. It enables users to find content by searching for particular words without understanding or exploring the entire website or app, a quick or less complex way to find content.</p>\n<p>Let's discuss why your website needs to have search functionality and its benefits.</p>\n<h2 id=\"eliminate-site-navigation-hustle\" style=\"position:relative;\"><a href=\"#eliminate-site-navigation-hustle\" aria-label=\"eliminate site navigation hustle permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Eliminate Site Navigation Hustle</h2>\n<p>If you have a large site -- assuming an e-commerce website or having hundreds of pages, users could find it extremely challenging to navigate to what they're looking for. In this situation, a search box allows your users to see what they need with a quick search.</p>\n<p>Regardless of where each user lands on your website, a search box will help them quickly find specific topics or pages.</p>\n<h2 id=\"improve-user-engagement-and-reduce-bounce-rate\" style=\"position:relative;\"><a href=\"#improve-user-engagement-and-reduce-bounce-rate\" aria-label=\"improve user engagement and reduce bounce rate permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Improve User Engagement and Reduce Bounce Rate</h2>\n<p>Simply, the more straightforward it is for users to navigate around your entire website, the more probable that they will explore it.</p>\n<p>If it's difficult for users to track down what they're looking for, they'll head off to somewhere else that can fulfill their requirements. Help your users engage quite a bit on your site with a search textbox.</p>\n<h2 id=\"take-advantage-of-search-functionality\" style=\"position:relative;\"><a href=\"#take-advantage-of-search-functionality\" aria-label=\"take advantage of search functionality permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Take Advantage of Search Functionality</h2>\n<p>Assuming you can incorporate your search bar into your Google Analytics, you'll have the option to track how frequently individuals look for a specific term. You can utilize this data for on-page content, order details, or billing plans.</p>\n<p>For example, if the most searched item on your website is <em>Perfume</em>, you could create a separate section or link on the home page so that users can directly navigate to that item faster.</p>\n<h2 id=\"mobile-users-prefer-search\" style=\"position:relative;\"><a href=\"#mobile-users-prefer-search\" aria-label=\"mobile users prefer search permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Mobile Users Prefer Search</h2>\n<p>In this mobile era, it's critical to ensure your site and applications are mobile-friendly. Whenever users are on their mobile phones, they could be out and in a hurry, and a search feature will allow them to search and navigate to a specific page rapidly.</p>\n<h2 id=\"its-a-distinct-feature-users-expect\" style=\"position:relative;\"><a href=\"#its-a-distinct-feature-users-expect\" aria-label=\"its a distinct feature users expect permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>It's A Distinct Feature Users Expect</h2>\n<p>People are habitual to using some features to the level that they don't think much before using them. Search functionality is one of them. In this digital world, you can't have a site that doesn't offer an ideal user experience. Keep in mind that this minor component can significantly help increase your website’s engagement rates.</p>\n<h2 id=\"helps-improve-branding\" style=\"position:relative;\"><a href=\"#helps-improve-branding\" aria-label=\"helps improve branding permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Helps Improve Branding</h2>\n<p>As the number of site visits increases, it indicates an improvement in brand engagement. Users visit your site because they are happy with the information and experience. This helps to raise your brand image among other competitors in your market.</p>\n<h2 id=\"reinforce-seo\" style=\"position:relative;\"><a href=\"#reinforce-seo\" aria-label=\"reinforce seo permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Reinforce SEO</h2>\n<p>A positive user experience will lead to more visits to your site. As the visitors' count and time spent on your website increase, search engines like Google will consider your website performing well and of good quality, which will further elevate your page rankings in search results.</p>\n<p>You will also find some new keywords from users' searches to search for similar or different information on Google or other search engines. These search keywords can be those words that you want to target in SEO and other marketing and search strategies.</p>\n<h2 id=\"boosts-growth\" style=\"position:relative;\"><a href=\"#boosts-growth\" aria-label=\"boosts growth permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Boosts Growth</h2>\n<p>As you expand your website with new content, blog posts, or new products, it can make your website cumbersome and affect user experience. Accordingly, finding an exact item can become difficult. However, with the right site search strategy, website size or navigation does not hamper the user experience. Users can find what they need and get ideas for other related items.</p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>In a nutshell, search functionality on your website helps offer a smooth, consistent experience for your users. And a well-implemented search functionality has more potential to ensure the website's success.</p>\n<p>Try not to stop your users from exploring all the features your site offers; add search functionality to your site soon!</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 24, 2022","updated_date":null,"description":"Adding a search functionality is important for any website to improve user experience. Read more to understand the benefits of enabling search on your website.","title":"Why Implement Search Functionality for Your Websites","tags":["Search"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/455ec841671081b53edc59522c28a138/58556/search-functionality.webp","srcSet":"/static/455ec841671081b53edc59522c28a138/61e93/search-functionality.webp 200w,\n/static/455ec841671081b53edc59522c28a138/1f5c5/search-functionality.webp 400w,\n/static/455ec841671081b53edc59522c28a138/58556/search-functionality.webp 800w,\n/static/455ec841671081b53edc59522c28a138/99238/search-functionality.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Neha Vyas","github":"nehavyasqa","avatar":null}}}}]},"markdownRemark":{"excerpt":"Introduction Ever wondered how apps like Spotify, Netflix, or Slack manage seamless login experiences across devices? Many of them use JWT…","fields":{"slug":"/engineering/how-to-integrate-jwt/"},"html":"<h2 id=\"introduction\" style=\"position:relative;\"><a href=\"#introduction\" aria-label=\"introduction permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Introduction</h2>\n<p>Ever wondered how apps like Spotify, Netflix, or Slack manage seamless login experiences across devices? Many of them use JWT, or JSON Web Tokens, a compact, stateless method for securely transmitting user identity and session data across services.</p>\n<p>With JWT token authentication, identity information is embedded in a signed token, allowing you to maintain user sessions without server-side storage. This approach is highly scalable and ideal for modern architectures like SPAs, mobile apps, and microservices.</p>\n<p>In this blog, we’ll walk you through what is JWT, why use it, and how to implement JWT authentication using LoginRadius. </p>\n<p>You’ll learn what JWT is, why it’s effective, and how it works in real-world applications. We'll cover both integration methods (IDX and Direct API), generating your signing key, managing sessions, storing the JWT token securely, and applying best practices throughout.</p>\n<p>Whether you're a developer, product manager, or IAM architect, this guide offers a complete foundation for implementing JWT token authentication into your application stack.</p>\n<h2 id=\"what-is-jwt\" style=\"position:relative;\"><a href=\"#what-is-jwt\" aria-label=\"what is jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is JWT?</h2>\n<p><a href=\"https://www.loginradius.com/blog/engineering/jwt/\">JSON Web Token (JWT)</a> is an open standard (RFC 7519) used to transmit information securely between parties as a JSON object. It’s compact, self-contained, and digitally signed, making it a reliable format for authentication and authorization across modern applications.</p>\n<p>A JWT consists of three parts:</p>\n<ol>\n<li><strong>Header –</strong> Contains metadata like the type of token and signing algorithm (e.g., HS256).</li>\n<li><strong>Payload –</strong> Stores the actual data or “claims,” such as user ID, roles, and token expiry.</li>\n<li><strong>Signature –</strong> A cryptographic hash that ensures the token hasn’t been tampered with.</li>\n</ol>\n<p><em>Example of a token structure:</em></p>\n<p>&#x3C;base64Header>.&#x3C;base64Payload>.&#x3C;signature></p>\n<h2 id=\"why-use-jwt\" style=\"position:relative;\"><a href=\"#why-use-jwt\" aria-label=\"why use jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Why Use JWT?</h2>\n<ul>\n<li><strong>Stateless Authentication</strong>: No server-side session storage is needed — the token holds all necessary user info. </li>\n<li><strong>Portable</strong>: Works seamlessly across domains, services, and APIs. </li>\n<li><strong>Scalable</strong>: Ideal for microservices, SPAs, mobile apps, and serverless functions. </li>\n<li><strong>Interoperable</strong>: JWTs are supported across many languages and frameworks.</li>\n</ul>\n<h2 id=\"how-jwt-works\" style=\"position:relative;\"><a href=\"#how-jwt-works\" aria-label=\"how jwt works permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How JWT Works?</h2>\n<p><img src=\"/f29edbf2978577390c7ffa02e9bc4dda/lr-JWT-authentication.webp\" alt=\"Flowchart illustrating LoginRadius JWT authentication via Identity Provider (IDP), showing user redirection from login icon to login page, authentication with IDP, JWT token validation, and subsequent redirection to the customer&#x27;s website or error page based on validation results.\"></p>\n<ol>\n<li>A user logs in with credentials. </li>\n<li>Your app (or identity provider like LoginRadius) issues a signed JWT. </li>\n<li>The client stores the token and sends it with each request (usually in the Authorization header). </li>\n<li>The server validates the token’s signature and claims. </li>\n<li>If valid, access is granted — without any session stored on the backend.</li>\n</ol>\n<p>JWT simplifies identity verification, especially when you're building apps that talk to APIs or need to scale without centralized session storage.</p>\n<h2 id=\"jwt-authentication-with-loginradius-overview\" style=\"position:relative;\"><a href=\"#jwt-authentication-with-loginradius-overview\" aria-label=\"jwt authentication with loginradius overview permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>JWT Authentication with LoginRadius: Overview</h2>\n<p>LoginRadius provides robust support for JWT (JSON Web Token) authentication, which allows for flexible and secure access control across different digital platforms. Whether you're building a fully custom identity flow or using a pre-built interface, the platform supports various integration approaches depending on your architecture.</p>\n<p>If you're looking to understand how to implement JWT token authentication effectively, LoginRadius offers two primary implementation models that cater to different levels of customization and control:</p>\n<h3 id=\"1-idx-implementation--jwt-through-a-hosted-login-page\" style=\"position:relative;\"><a href=\"#1-idx-implementation--jwt-through-a-hosted-login-page\" aria-label=\"1 idx implementation  jwt through a hosted login page permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. IDX Implementation – JWT through a Hosted Login Page</h3>\n<p>The IDX-hosted login approach enables secure, standards-compliant, JWT-based authentication without requiring you to build a custom login interface. This is a strategic option for fast, compliant, and user-friendly deployments.</p>\n<ul>\n<li>The Identity Experience Framework (IDX) comes with a fully custom branded hosted login page.</li>\n<li>Once the user logs in and gets enrolled, the user’s JWTs are automatically generated and issued. These tokens can be utilized for managing user sessions and accessing the APIs.</li>\n<li>This approach simplifies deployment without compromising on user experience and security standards.</li>\n</ul>\n<h3 id=\"configuration-steps\" style=\"position:relative;\"><a href=\"#configuration-steps\" aria-label=\"configuration steps permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>Configuration Steps:</strong></h3>\n<ol>\n<li>Enable JWT Login</li>\n<li>Go to <a href=\"https://console.loginradius.com/authentication/authentication-configuration\">authentication configuration settings</a> and enable JWT Login in the Admin Console.</li>\n</ol>\n<p><img src=\"/9fb19dd9c88c7916aeebd03ab6e661b7/lr-admin-console.webp\" alt=\"Screenshot of LoginRadius Admin Console showing JWT Custom IDP configuration interface with options for provider name, algorithm (HS256), key entry, clock skew, and expiration time settings.\"></p>\n<ol start=\"2\">\n<li>Specify your signing algorithm and expiry policy, and define your JWT Secret Key.</li>\n<li>Input a secure JWT signing key.</li>\n<li>Specify token expiry duration (e.g., 15–60 minutes)</li>\n<li>Select the desired algorithm —HS256 for symmetric signing (same key signs and verifies)</li>\n<li>RS256 for asymmetric signing, where LoginRadius securely stores the private key used to sign the JWT.</li>\n<li>Your app or backend service uses the public key to validate the token signature.</li>\n<li>LoginRadius provides a JWKS (JSON Web Key Set) endpoint to dynamically fetch and rotate public keys, ensuring trust without key exposure.</li>\n<li>Update IDX Template for Callback</li>\n<li>Modify your IDX login page template to retrieve the JWT post-login. You can access the token via redirect URL parameters or secure JavaScript callbacks.</li>\n</ol>\n<h3 id=\"example-response\" style=\"position:relative;\"><a href=\"#example-response\" aria-label=\"example response permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example Response:</h3>\n<p>{</p>\n<p>  \"access_token\": \"eyJhbGciOiJIUzI1NiIsInR...\",</p>\n<p>  \"expires_in\": 1800</p>\n<p>}</p>\n<p>This integration approach works best for all teams that want effective identity workflows without the complexity of building proprietary login screens, something that is crucial for customer portals, onboarding of mobile applications, and even managing access for business partners.</p>\n<h3 id=\"2-direct-api-implementation--self-managed-login\" style=\"position:relative;\"><a href=\"#2-direct-api-implementation--self-managed-login\" aria-label=\"2 direct api implementation  self managed login permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. Direct API Implementation – Self Managed Login</h3>\n<p>If you’re building a custom login UI or working in a headless environment, LoginRadius lets you generate and handle JWTs directly through its <a href=\"https://www.loginradius.com/docs/api/v2/customer-identity-api/\">Authentication APIs</a>. Here’s how you can programmatically perform token authentication using the classic method:</p>\n<ul>\n<li>For custom front-end applications, LR offers an API to authenticate users and issue JWT tokens.</li>\n<li>In response to the login request, the developers are provided with signed tokens that can be validated on the client’s side or by downstream services.</li>\n<li>This method is best fit for enterprise applications that have complex custom workflows or are designed to be embedded into other applications.</li>\n</ul>\n<h3 id=\"configuration-steps-1\" style=\"position:relative;\"><a href=\"#configuration-steps-1\" aria-label=\"configuration steps 1 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>Configuration Steps:</strong></h3>\n<h4 id=\"step-1-authenticate-via-api\" style=\"position:relative;\"><a href=\"#step-1-authenticate-via-api\" aria-label=\"step 1 authenticate via api permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 1: Authenticate via API:</h4>\n<ul>\n<li>\n<p>Send a POST login request to the LR Authentication URL: </p>\n<p>POST /identity/v2/auth/login</p>\n</li>\n</ul>\n<p>Include the user’s credentials (email + password) in the request body.</p>\n<h4 id=\"step-2-get-jwt-in-response\" style=\"position:relative;\"><a href=\"#step-2-get-jwt-in-response\" aria-label=\"step 2 get jwt in response permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 2: Get JWT in Response</h4>\n<ul>\n<li>If the user credentials are authentic, then the JWT token will be available in response.</li>\n</ul>\n<p>{</p>\n<p> \"access_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",</p>\n<p> \"expires_in\": 3600</p>\n<p>}</p>\n<h4 id=\"step-3-jwt-decoding-and-validation\" style=\"position:relative;\"><a href=\"#step-3-jwt-decoding-and-validation\" aria-label=\"step 3 jwt decoding and validation permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 3: JWT Decoding and Validation</h4>\n<ul>\n<li>Use any JWT library (e.g., jsonwebtoken for Node.js or pyjwt for Python) to decode the token.</li>\n<li>Validate the signature using your configured secret key.</li>\n<li>Confirm claims like exp, iat, aud, and iss.</li>\n</ul>\n<h4 id=\"step-4-set-custom-claims-optional\" style=\"position:relative;\"><a href=\"#step-4-set-custom-claims-optional\" aria-label=\"step 4 set custom claims optional permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 4: Set Custom Claims (Optional)</h4>\n<p>With LoginRadius, it is possible to customize the payload to include user roles and/or any additional metadata. You can set custom JWT claims on the Admin Console.</p>\n<p>With this method, you have complete customization over login flows while using LoginRadius to issue signed JWTs for user session management.</p>\n<p><strong>NOTE-</strong> With either method, LoginRadius ensures that JWTs are securely signed, optionally short-lived, and compatible with standard token validation libraries, making integration seamless for everyone.</p>\n<p>To get started with JWT implementation, you can<a href=\"https://www.loginradius.com/docs/single-sign-on/federated-sso/jwt-login/jwt-implementation-guide/\"> read our complete developer documentation</a>. </p>\n<h2 id=\"hosted-login-vs-direct-api\" style=\"position:relative;\"><a href=\"#hosted-login-vs-direct-api\" aria-label=\"hosted login vs direct api permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Hosted Login vs Direct API</h2>\n<p><img src=\"/15ec02ac98d24a9f1f28e5d0f06b9174/IDX-vs-Direct-API-JWT.webp\" alt=\"Illustration showing IDX vs Direct API JWT flow diagram comparing LoginRadius JWT authentication methods via Hosted Login Page (IDX) and Custom Login UI using Direct API, illustrating user login, JWT issuance, and token return process.\"></p>\n<h2 id=\"what-is-session-management-and-how-it-works-with-jwt\" style=\"position:relative;\"><a href=\"#what-is-session-management-and-how-it-works-with-jwt\" aria-label=\"what is session management and how it works with jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is Session Management and How It Works with JWT</h2>\n<p><a href=\"https://www.loginradius.com/blog/identity/user-session-management/\">Session management </a>is how your app keeps track of a user after they log in so they don’t have to prove who they are with every request.</p>\n<p>In traditional apps, sessions are stored on the server using session IDs. Every time a request comes in, the server checks that session ID to verify the user.</p>\n<p>In modern apps, especially SPAs and APIs, JWTs are used to manage sessions without needing server-side storage; this is called stateless session management. The token itself carries the user’s identity, roles, and expiration details. As long as the token is valid, the user stays logged in.</p>\n<p>Good session management ensures:</p>\n<ul>\n<li>Security against session hijacking</li>\n<li>Fast user validation without hitting a database</li>\n<li>Smooth experiences with token refresh strategies</li>\n</ul>\n<h2 id=\"how-loginradius-handles-session-management-with-jwt\" style=\"position:relative;\"><a href=\"#how-loginradius-handles-session-management-with-jwt\" aria-label=\"how loginradius handles session management with jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How LoginRadius Handles Session Management with JWT:</h2>\n<ol>\n<li>\n<p>User Logs In </p>\n<ul>\n<li>LoginRadius returns an access token (JWT) and, optionally, a refresh token.</li>\n</ul>\n</li>\n<li>\n<p>Client Stores the Token </p>\n<ul>\n<li>Access tokens are stored in memory, sessionStorage, or secure cookies. </li>\n<li>They’re sent on every request via the Authorization: Bearer header. </li>\n</ul>\n</li>\n<li>\n<p>Access Token Expiry </p>\n<ul>\n<li>These tokens are short-lived by design (e.g., 15–30 minutes). </li>\n<li>Once expired, the client can use the refresh token to request a new access token. </li>\n</ul>\n</li>\n<li>\n<p>Token Renewal </p>\n<ul>\n<li>LoginRadius validates the refresh token and issues a new JWT, i.e., no user re-authentication is needed. </li>\n<li>Refresh tokens can be revoked at any time.</li>\n</ul>\n</li>\n<li>Logout and Token Revocation Strategy</li>\n</ol>\n<p>When the user logs out, both the access token and refresh token should be cleared from client storage.</p>\n<ul>\n<li>The refresh token can be explicitly revoked via the LoginRadius API, terminating the ability to renew sessions. </li>\n<li>\n<p>However, access tokens are stateless and cannot be revoked mid-lifecycle unless: </p>\n<ul>\n<li>You maintain a blacklist of token IDs (jti claims) and check them on each request. </li>\n<li>You use short-lived access tokens to limit exposure naturally. </li>\n<li>Or, you rotate your JWT signing key, invalidating all previously issued tokens. </li>\n</ul>\n</li>\n</ul>\n<p>Combining these strategies gives you greater control over token misuse and enables a robust, enterprise-grade logout flow. </p>\n<p><a href=\"https://www.loginradius.com/resource/whitepaper/secure-api-using-oauth2\"><img src=\"/e55ae4bbc8ce62e13f03e46e29ebe7cc/api-economy.webp\" alt=\"illustration showing LoginRadius free downloadable resource named API economy is transforming digitization: how to secure it using oauth 2.0.\"></a></p>\n<h2 id=\"how-to-store-jwt-tokens\" style=\"position:relative;\"><a href=\"#how-to-store-jwt-tokens\" aria-label=\"how to store jwt tokens permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to Store JWT Tokens?</h2>\n<p>When you implement JWT-based authentication, the client (browser or mobile app) needs a way to store the access token and, optionally, the refresh token after they are issued by the authentication server. This stored token is then attached to every subsequent request to prove the user's identity.</p>\n<p>Choosing where to store the JWT is a crucial security decision. The most common storage options are:</p>\n<ul>\n<li>localStorage</li>\n<li>sessionStorage</li>\n<li>HTTP-only cookies</li>\n</ul>\n<p>Each option has trade-offs between security, accessibility, and persistence, and the right choice depends on your application's architecture and threat model.</p>\n<h4 id=\"recommended-storage-strategy\" style=\"position:relative;\"><a href=\"#recommended-storage-strategy\" aria-label=\"recommended storage strategy permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Recommended Storage Strategy</h4>\n<ul>\n<li>\n<p>Access Tokens </p>\n<ul>\n<li>For SPAs: store in memory or sessionStorage for short-term access </li>\n<li>If stored in the browser, protect against XSS </li>\n</ul>\n</li>\n<li>\n<p>Refresh Tokens</p>\n<ul>\n<li>Always store the JWT refresh token in HTTP-only secure cookies to prevent JavaScript access. This adds a critical layer of protection against XSS attacks.</li>\n<li>Combine with SameSite=Strict or SameSite=Lax attributes to mitigate CSRF risks and ensure the JWT refresh token is only sent in intended contexts.</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"best-practices-for-storing-jwts\" style=\"position:relative;\"><a href=\"#best-practices-for-storing-jwts\" aria-label=\"best practices for storing jwts permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Best Practices for Storing JWTs</h2>\n<ol>\n<li>Never store sensitive tokens (like refresh tokens) in localStorage or sessionStorage.</li>\n<li>Use Secure and HttpOnly flags with cookies to prevent JavaScript access and ensure transmission only over HTTPS.</li>\n<li>Set the SameSite=Strict or Lax attribute on cookies to protect against CSRF.</li>\n<li>Use short-lived access tokens and rotate refresh tokens regularly.</li>\n<li>Implement CSP (Content Security Policy) to reduce XSS risk.</li>\n<li>Avoid storing any tokens in frontend code (e.g., hardcoded in JS files).</li>\n</ol>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>JWT authentication with LoginRadius offers a modern, stateless approach to managing sessions across distributed systems. The IDX integration is ideal for rapid deployment, while the Direct API model is best for organizations needing deep customization and integration flexibility.</p>\n<p>With robust token signing, refresh capabilities, and centralized control, LoginRadius provides a future-ready foundation for secure, scalable identity architecture. <a href=\"https://www.loginradius.com/contact-us?utm_source=blog&#x26;utm_medium=web&#x26;utm_campaign=how-to-integrate-jwt\">Contact us</a> to know more about JWT authentication and implementation guide. </p>\n<h2 id=\"faqs\" style=\"position:relative;\"><a href=\"#faqs\" aria-label=\"faqs permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>FAQs</h2>\n<h3 id=\"1-what-is-jwt-authentication-used-for\" style=\"position:relative;\"><a href=\"#1-what-is-jwt-authentication-used-for\" aria-label=\"1 what is jwt authentication used for permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. What is JWT authentication used for?</h3>\n<p><strong>A:</strong> JWT authentication securely verifies user identities, enabling stateless session management across web, mobile apps, and microservices without server-side session storage.</p>\n<h3 id=\"2-how-does-loginradius-simplify-jwt-integration\" style=\"position:relative;\"><a href=\"#2-how-does-loginradius-simplify-jwt-integration\" aria-label=\"2 how does loginradius simplify jwt integration permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. How does LoginRadius simplify JWT integration?</h3>\n<p><strong>A:</strong> LoginRadius simplifies JWT integration by offering hosted <a href=\"https://www.loginradius.com/docs/single-sign-on/federated-sso/jwt-login/jwt-implementation-guide/\">IDX login pages </a>and direct API-based authentication methods, enabling rapid deployment and deep customization.</p>\n<h3 id=\"3-is-jwt-authentication-secure\" style=\"position:relative;\"><a href=\"#3-is-jwt-authentication-secure\" aria-label=\"3 is jwt authentication secure permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3. Is JWT authentication secure?</h3>\n<p><strong>A:</strong> Yes, JWT authentication is secure when implemented with best practices like short-lived tokens, secure storage methods, signature validation, and refresh token rotation.</p>\n<h3 id=\"4-can-jwt-tokens-be-revoked-with-loginradius\" style=\"position:relative;\"><a href=\"#4-can-jwt-tokens-be-revoked-with-loginradius\" aria-label=\"4 can jwt tokens be revoked with loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>4. Can JWT tokens be revoked with LoginRadius?</h3>\n<p><strong>A:</strong> Yes, LoginRadius allows<a href=\"https://www.loginradius.com/docs/api/v2/customer-identity-api/refresh-token/revoke-refresh-token/?q=revoke+jwt\"> revocation of JWT</a> refresh tokens explicitly, and supports strategies like short-lived tokens and key rotation to manage token lifecycles securely.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"April 15, 2025","updated_date":null,"description":"Discover JWT (JSON Web Token) authentication, its advantages, and how to integrate it seamlessly using LoginRadius' hosted IDX and Direct API methods for secure, scalable identity management.","title":"JWT Authentication with LoginRadius: Quick Integration Guide","tags":["JWT","JSON Web Token","Authentication","Authorization"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":0.7782101167315175,"src":"/static/4cedb7829f98208cbc6d5a9aea4e983d/58556/how-to-integrate-jwt.webp","srcSet":"/static/4cedb7829f98208cbc6d5a9aea4e983d/61e93/how-to-integrate-jwt.webp 200w,\n/static/4cedb7829f98208cbc6d5a9aea4e983d/1f5c5/how-to-integrate-jwt.webp 400w,\n/static/4cedb7829f98208cbc6d5a9aea4e983d/58556/how-to-integrate-jwt.webp 800w,\n/static/4cedb7829f98208cbc6d5a9aea4e983d/1cc9f/how-to-integrate-jwt.webp 896w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Kundan Singh","github":null,"avatar":null}}}},"pageContext":{"limit":6,"skip":18,"currentPage":4,"type":"//engineering//","numPages":53,"pinned":"5c425581-f474-5ae9-abe7-cf5342db2aaa"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}