{"componentChunkName":"component---src-templates-tag-js","path":"/tags/jwt/","result":{"data":{"site":{"siteMetadata":{"title":"LoginRadius Blog"}},"allMarkdownRemark":{"totalCount":18,"edges":[{"node":{"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,"title":"JWT Authentication with LoginRadius: Quick Integration Guide","tags":["JWT","JSON Web Token","Authentication","Authorization"],"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}}}},{"node":{"fields":{"slug":"/engineering/guest-post/how-to-implement-jwt-authentication-in-deno/"},"html":"<h2 id=\"introduction\" style=\"position:relative;\"><a href=\"#introduction\" aria-label=\"introduction permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Introduction</h2>\n<p>It is essential to protect your APIs for a secure experience, and <strong>JSON Web Token</strong> (JWT) authentication allows you to protect your APIs so that an unauthorized person will not have access.</p>\n<h2 id=\"prerequisites\" style=\"position:relative;\"><a href=\"#prerequisites\" aria-label=\"prerequisites permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Prerequisites</h2>\n<p>This is a hands-on tutorial to follow. To get the most out of it, ensure you have:</p>\n<ul>\n<li>A code editor of your choice</li>\n<li>Basic knowledge of JavaScript/<a href=\"https://www.typescriptlang.org/\">TypeScript</a>.</li>\n<li>Basic knowledge of <a href=\"https://www.mongodb.com/\">MongoDB</a></li>\n<li><a href=\"https://www.postman.com/\">Postman</a> or <a href=\"https://insomnia.rest/\">Insomia</a> installed</li>\n</ul>\n<h2 id=\"what-is-deno\" style=\"position:relative;\"><a href=\"#what-is-deno\" aria-label=\"what is deno permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Deno?</h2>\n<p><a href=\"https://deno.land/\">Deno</a> is developed in Rust. It is a modern runtime environment for JavaScript/TypeScript and a WebAssembly that uses the Google V8 engine. It is simple and safe. It implements web platform standards and provides web platform capabilities.</p>\n<p>Deno’s features are intended to enhance Node.js’s capabilities. It’s secure by default, with no access to files, networks, or the environment except explicitly enabled. And it supports both JavaScript and TypeScript out of the box.</p>\n<h2 id=\"why-use-deno\" style=\"position:relative;\"><a href=\"#why-use-deno\" aria-label=\"why use deno permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Deno?</h2>\n<p>Deno is a well-thought-out modular system. Apart from its simplicity and high security, there are so many other reasons to use Deno:</p>\n<ul>\n<li>Outside of an async function, you can use await</li>\n<li>No setting is required for TypeScript to work</li>\n<li>There are no dependencies, and it ships as a single executable</li>\n<li>A dependency inspector and a code formatter are built-in</li>\n<li>Packages in Deno are decentralized</li>\n</ul>\n<h2 id=\"what-is-json-web-token\" style=\"position:relative;\"><a href=\"#what-is-json-web-token\" aria-label=\"what is json web token permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is JSON Web Token?</h2>\n<p>JSON Web Token, popularly called JWT, is an open standard that offers a concise and self-contained method for securely transferring data between parties as a JSON object. It holds information in an easy-to-access format for developers and computers; the token's compact size makes it simple to send through URL, POST parameter, or HTTP header. It allows two parties — a client and a server — to share information securely. A secret or public/private key pair is used to digitally sign the information in a JWT. </p>\n<p>Authentication is the primary use of JWT. It is assigned to a user after they sign in to an application, and with the assigned JWT, a user can request other routes.</p>\n<h2 id=\"install-deno\" style=\"position:relative;\"><a href=\"#install-deno\" aria-label=\"install deno permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Install Deno</h2>\n<p>Without too many shenanigans, let's start by installing Deno!</p>\n<p>Deno installation in Windows isn't as smooth sailing as on Mac or Linux. Unlike in Node.js, where you run a command on your terminal, Deno in Windows can be installed using PowerShell, Scoop (a command-line installer), or Chocolatey (a package manager). <a href=\"https://deno.land/manual/getting_started/installation\">Click here for the guide on how to install Deno</a>.</p>\n<p>To install Deno with PowerShell, open your PowerShell and run the following command:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">iwr https://deno.land/x/install/install.ps1 -useb | iex</span></code></pre>\n<p>Relax while Deno is being installed. When completed, exit PowerShell and close and reopen a terminal. The new PATH is activated by closing and reopening the terminal. Now that you have installed Deno, let's check the version of Deno.</p>\n<p>To check the version of your installed Deno, run: <code>deno -V</code></p>\n<h2 id=\"project-setup\" style=\"position:relative;\"><a href=\"#project-setup\" aria-label=\"project setup permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Project Setup</h2>\n<p>With installation out of the way, let us set up your project. Create a folder <code>DenoAPI_JWT_Auth</code>; you can call it any name you choose. Create an <code>app.ts</code> file and a folder <code>src</code> in your folder.</p>\n<p>Inside your <code>src</code> folder, create the following folders: <code>controllers</code>, <code>database</code>, <code>middlewares</code>, <code>routes</code>, <code>schema</code>, and <code>utils</code>.</p>\n<p>Your project directory should look as follows:</p>\n<p><code>DenoAPI_JWT_Auth</code>  </p>\n<p>│\n└─<strong>src</strong><br>\n│   └───controllers<br>\n│   │\n│   └───database<br>\n│   │\n│   └───middlewares<br>\n│   │\n│   └───routes<br>\n│   │\n│   └───schema<br>\n│   │\n│   └───utils<br>\n└─<strong>app.ts</strong>  </p>\n<h2 id=\"create-oak-server\" style=\"position:relative;\"><a href=\"#create-oak-server\" aria-label=\"create oak server permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create Oak Server</h2>\n<p>Next is to create your Oak server. <a href=\"https://oakserver.github.io/oak/\">Oak</a> is a Deno middleware system that provides a router middleware for HTTP servers.</p>\n<p>Go to <code>app.ts</code>, import Application from the Deno Oak URL, create an instance of the application, define your port, and call a middleware, as follows.</p>\n<p><code>app.ts</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Application</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/x/oak/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">app</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Application</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">PORT</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">8080</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">((</span><span class=\"mtk12\">ctx</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span><span class=\"mtk12\">ctx</span><span class=\"mtk1\">.</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&#39;Welcome&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">next</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       });</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">`Application is listening on port: </span><span class=\"mtk4\">${</span><span class=\"mtk12\">PORT</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">listen</span><span class=\"mtk1\">({</span><span class=\"mtk12\">port:PORT</span><span class=\"mtk1\">});</span></span></code></pre>\n<p>Let's quickly run your server: to run the server, use <code>deno run --allow-net app.ts</code> </p>\n<p>Deno will always request permission to use your network. <code>--allow-net</code> gives Deno permission to all network calls.</p>\n<p>You should see <code>Application is listening on port: 8080</code></p>\n<p>Now, in your <code>routes</code> folder, create a file called <code>allRoutes.ts</code>, and set up your router by importing <code>Router</code> from the oak URL, then create an instance of the router and export the default router.</p>\n<p><code>routes.allRoutes.ts</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Router</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/x/oak/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Router</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\">;</span></span></code></pre>\n<p>Moving on, you need to modify <code>app.ts</code>. So, go to <code>app.ts</code> and import the router. Let the app use <code>router.routes()</code> and <code>router.allowedMethods()</code> methods, then remove the middleware, so it doesn't overshadow the imported routes. The <code>allowedMethods()</code> tells Deno to include all routes by your router.</p>\n<p><code>app.ts</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Application</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/x/oak/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./src/routes/allRoutes.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">app</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Application</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">PORT</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">8080</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">routes</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">allowedMethods</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">`Application is listening on port: </span><span class=\"mtk4\">${</span><span class=\"mtk12\">PORT</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">listen</span><span class=\"mtk1\">({</span><span class=\"mtk12\">port:PORT</span><span class=\"mtk1\">});</span></span></code></pre>\n<p>You can rerun your app with the same command: <code>deno run --allow-net app.ts</code></p>\n<h2 id=\"create-user-data\" style=\"position:relative;\"><a href=\"#create-user-data\" aria-label=\"create user data permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create User Data</h2>\n<p>Now, you need to create user data. But before that, let's connect your application to the MongoDB database.</p>\n<ul>\n<li>Go to your <code>database</code> folder</li>\n<li>Create a file called <code>connectBD.ts</code></li>\n<li>Import MongoClient from the Deno MongoDB URL</li>\n<li>Create an instance of MongoClient</li>\n<li>Connect your database</li>\n<li>Export default</li>\n</ul>\n<p><code>database.connectDB.ts</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">MongoClient</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/x/mongo@v0.30.0/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk3\">// Connecting to a Mongo Database</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">client</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">MongoClient</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\">dbString</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;DB_String&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">client</span><span class=\"mtk1\">.</span><span class=\"mtk11\">connect</span><span class=\"mtk1\">(</span><span class=\"mtk12\">dbString</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Database connected!&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">db</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">client</span><span class=\"mtk1\">.</span><span class=\"mtk11\">database</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;deno_auth&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">db</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span></span></code></pre>\n<p>With that out of the way, let's create an interface for your database.</p>\n<p>In your <code>schema</code> folder, create a file <code>user.ts</code>, import objectId from deno MongoDB URL, then define and export your schema.</p>\n<p><code>schema.user.ts</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span><span class=\"mtk12\">ObjectId</span><span class=\"mtk1\">} </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/x/mongo@v0.30.0/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">interface</span><span class=\"mtk1\"> </span><span class=\"mtk10\">UserSchema</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">_id</span><span class=\"mtk1\">: </span><span class=\"mtk10\">ObjectId</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">username</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">password</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span></code></pre>\n<p>Let's play with some logic: go to your <code>controllers</code> folder, and create a file called <code>users.ts</code>. In the file, import your database and UserSchema.</p>\n<p>It's not a good practice to store your password in plain text for security reasons. To has your password, let's import bcrypt from the deno bcrypt URL.</p>\n<p>So, create a function called <code>signup</code> that takes username and password. Take the user details from the request body, hash the password, and save them to your database.</p>\n<p><code>controllers.users.ts</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">db</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../database/connectBD.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk4\">*</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/x/bcrypt/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UserSchema</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../schema/user.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Users</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">db</span><span class=\"mtk1\">.</span><span class=\"mtk11\">collection</span><span class=\"mtk1\">&lt;</span><span class=\"mtk10\">UserSchema</span><span class=\"mtk1\">&gt;(</span><span class=\"mtk8\">&quot;users&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">signup</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\">({</span><span class=\"mtk12\">request</span><span class=\"mtk1\">, </span><span class=\"mtk12\">response</span><span class=\"mtk1\">}:{</span><span class=\"mtk12\">request</span><span class=\"mtk1\">:</span><span class=\"mtk10\">any</span><span class=\"mtk1\">;</span><span class=\"mtk12\">response</span><span class=\"mtk1\">:</span><span class=\"mtk10\">any</span><span class=\"mtk1\">}) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> {</span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\">} = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">request</span><span class=\"mtk1\">.</span><span class=\"mtk11\">body</span><span class=\"mtk1\">().</span><span class=\"mtk12\">value</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">salt</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">genSalt</span><span class=\"mtk1\">(</span><span class=\"mtk7\">8</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">hashedPassword</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">hash</span><span class=\"mtk1\">(</span><span class=\"mtk12\">password</span><span class=\"mtk1\">, </span><span class=\"mtk12\">salt</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">_id</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Users</span><span class=\"mtk1\">.</span><span class=\"mtk11\">insertOne</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">username</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">password:hashedPassword</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> =</span><span class=\"mtk7\">201</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User created&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">userId:_id</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user:username</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span></code></pre>\n<p>Now, head over to <code>allRoutes.ts</code> in your <code>routes</code> folder, import the <code>signup</code> function from the controller, and create a POST route for <code>signup</code>, as follows.</p>\n<p><code>routes.allRoutes.ts</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">import { Router } from &quot;https://deno.land/x/oak/mod.ts&quot;;</span>\n<span class=\"grvsc-line\">import {signup} from &quot;../controllers/users.ts&quot;;</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">const router = new Router();</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">//User routes</span>\n<span class=\"grvsc-line\">router.post(&quot;/api/signup&quot;, signup)</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">export default router;</span></code></pre>\n<h2 id=\"create-authenticate-user-route\" style=\"position:relative;\"><a href=\"#create-authenticate-user-route\" aria-label=\"create authenticate user route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create Authenticate User route</h2>\n<p>Next, create an authentication route that authenticates your user route. The latest version of Deno does not allow a string as a secret key but accepts a cryptokey generated from a <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/generateKey\">Web Crypto API</a> with the <code>generatekey()</code> method of the <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto\">SubtleCrypto</a> interface.</p>\n<p>So, head over to your <code>utils</code> folder, create a file called <code>apiKey.ts</code>,  and in the file, generate your key and export it, as follows.</p>\n<p><code>utils.apiKey.ts</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">key</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">crypto</span><span class=\"mtk1\">.</span><span class=\"mtk12\">subtle</span><span class=\"mtk1\">.</span><span class=\"mtk11\">generateKey</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    { </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;HMAC&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">hash:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;SHA-512&quot;</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><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=\"mtk8\">&quot;sign&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;verify&quot;</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  );</span></span></code></pre>\n<p>Now that you have successfully created your key, you can create a user authentication route so that every user that logs in will get authenticated.</p>\n<p>Head over to <code>user.ts</code> in your controller, import the API key, create a <code>signin</code> function, and write some validation logic to validate that the user exists in your database. If validation is successful, you create a token to authenticate the user. </p>\n<h2 id=\"using-jwt-to-authenticate-a-user\" style=\"position:relative;\"><a href=\"#using-jwt-to-authenticate-a-user\" aria-label=\"using jwt to authenticate 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>Using JWT to Authenticate a User</h2>\n<p>Now, let's import Deno JWT (djwt) <code>create</code> function from the URL to create a token. When a user logs in, take the id and username, pass the payload into the JWT <code>create</code> function, generate a token, and use the token to authenticate the user.</p>\n<p><code>controllers.users.ts</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">db</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../database/connectDB.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk4\">*</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/x/bcrypt/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">UserSchema</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../schema/user.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">create</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/x/djwt@v2.4/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">key</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../utils/apiKey.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Users</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">db</span><span class=\"mtk1\">.</span><span class=\"mtk11\">collection</span><span class=\"mtk1\">&lt;</span><span class=\"mtk10\">UserSchema</span><span class=\"mtk1\">&gt;(</span><span class=\"mtk8\">&quot;users&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">//create a user</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">signup</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\">({</span><span class=\"mtk12\">request</span><span class=\"mtk1\">, </span><span class=\"mtk12\">response</span><span class=\"mtk1\">}:{</span><span class=\"mtk12\">request</span><span class=\"mtk1\">:</span><span class=\"mtk10\">any</span><span class=\"mtk1\">;</span><span class=\"mtk12\">response</span><span class=\"mtk1\">:</span><span class=\"mtk10\">any</span><span class=\"mtk1\">}) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> {</span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\">} = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">request</span><span class=\"mtk1\">.</span><span class=\"mtk11\">body</span><span class=\"mtk1\">().</span><span class=\"mtk12\">value</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">salt</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">genSalt</span><span class=\"mtk1\">(</span><span class=\"mtk7\">8</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">hashedPassword</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">hash</span><span class=\"mtk1\">(</span><span class=\"mtk12\">password</span><span class=\"mtk1\">, </span><span class=\"mtk12\">salt</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">_id</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Users</span><span class=\"mtk1\">.</span><span class=\"mtk11\">insertOne</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">username</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">password:hashedPassword</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> =</span><span class=\"mtk7\">201</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User created&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">userId:_id</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user:username</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=\"mtk3\">//sign in a user</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">signin</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> ({</span><span class=\"mtk12\">request</span><span class=\"mtk1\">, </span><span class=\"mtk12\">response</span><span class=\"mtk1\">}:{</span><span class=\"mtk12\">request</span><span class=\"mtk1\">:</span><span class=\"mtk10\">any</span><span class=\"mtk1\">; </span><span class=\"mtk12\">response</span><span class=\"mtk1\">:</span><span class=\"mtk10\">any</span><span class=\"mtk1\">}) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">request</span><span class=\"mtk1\">.</span><span class=\"mtk11\">body</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> {</span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\">} = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">body</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Users</span><span class=\"mtk1\">.</span><span class=\"mtk11\">findOne</span><span class=\"mtk1\">({</span><span class=\"mtk12\">username</span><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\">(!</span><span class=\"mtk12\">user</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">404</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">`user &quot;</span><span class=\"mtk4\">${</span><span class=\"mtk12\">username</span><span class=\"mtk4\">}</span><span class=\"mtk8\">&quot; not found`</span><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">confirmPassword</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">compare</span><span class=\"mtk1\">(</span><span class=\"mtk12\">password</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">password</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\">(!</span><span class=\"mtk12\">confirmPassword</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">404</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Incorrect password&quot;</span><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">//authenticate a user</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">payload</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">_id</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">username</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\"> =  </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">create</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">alg:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;HS512&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">typ:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;JWT&quot;</span><span class=\"mtk1\"> }, { </span><span class=\"mtk12\">payload</span><span class=\"mtk1\"> }, </span><span class=\"mtk12\">key</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\">(</span><span class=\"mtk12\">jwt</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">200</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">userId:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">_id</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">token:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\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\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">500</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;internal server error&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span></code></pre>\n<p>So far, you have progressed well. The next thing is to import your <code>signin</code> function in the routes and create a post request for it, as follows.</p>\n<p><code>routes.allRoutes.ts</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Router</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/x/oak/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span><span class=\"mtk12\">signup</span><span class=\"mtk1\">, </span><span class=\"mtk12\">signin</span><span class=\"mtk1\">} </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../controllers/users.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Router</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//User routes</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/api/signup&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">signup</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\">&quot;/api/signin&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">signin</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\">;</span></span></code></pre>\n<p>Congratulations on making it this far! You are through with the authentication route. Now, you can register a user, sign in, and authenticate the user. </p>\n<p>You need to create your todo CRUD API and protect the routes so that a random person will not be able to access your route except when authenticated.</p>\n<p>Go to your <code>schema</code> folder, and create a file <code>task.ts</code>. In the file, create your tasks interface and export it.</p>\n<h2 id=\"create-todo-route\" style=\"position:relative;\"><a href=\"#create-todo-route\" aria-label=\"create todo route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create Todo Route</h2>\n<p><code>schema.task.ts</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">interface</span><span class=\"mtk1\"> </span><span class=\"mtk10\">TaskSchema</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">name</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">isCompleted</span><span class=\"mtk1\">: </span><span class=\"mtk10\">boolean</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span></span></code></pre>\n<p>After successfully creating the task interface, move to our controller, create a file <code>tasks.ts</code>, and import the database, schema, and object Id. Then write the logic for our todo CRUD API.</p>\n<p><code>controllers.tasks.ts</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"12\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">db</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../database/connectDB.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">TaskSchema</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../schema/task.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span><span class=\"mtk12\">ObjectId</span><span class=\"mtk1\">} </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/x/mongo@v0.30.0/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">tasks</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">db</span><span class=\"mtk1\">.</span><span class=\"mtk11\">collection</span><span class=\"mtk1\">&lt;</span><span class=\"mtk10\">TaskSchema</span><span class=\"mtk1\">&gt;(</span><span class=\"mtk8\">&quot;tasks&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">create</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\">({</span><span class=\"mtk12\">request</span><span class=\"mtk1\">, </span><span class=\"mtk12\">response</span><span class=\"mtk1\">}:{</span><span class=\"mtk12\">request</span><span class=\"mtk1\">:</span><span class=\"mtk10\">any</span><span class=\"mtk1\">;</span><span class=\"mtk12\">response</span><span class=\"mtk1\">:</span><span class=\"mtk10\">any</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\">name</span><span class=\"mtk1\">, </span><span class=\"mtk12\">isCompleted</span><span class=\"mtk1\">} = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">request</span><span class=\"mtk1\">.</span><span class=\"mtk11\">body</span><span class=\"mtk1\">().</span><span class=\"mtk12\">value</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">_id</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">tasks</span><span class=\"mtk1\">.</span><span class=\"mtk11\">insertOne</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">name</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">isCompleted</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Task created!!&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">id:_id</span><span class=\"mtk1\">, </span><span class=\"mtk12\">name:name</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Completed:isCompleted</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=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">getTasks</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> ({</span><span class=\"mtk12\">response</span><span class=\"mtk1\">}:{</span><span class=\"mtk12\">response</span><span class=\"mtk1\">:</span><span class=\"mtk10\">any</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\">allTasks</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">tasks</span><span class=\"mtk1\">.</span><span class=\"mtk11\">find</span><span class=\"mtk1\">({}).</span><span class=\"mtk11\">toArray</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">200</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span><span class=\"mtk12\">tasks:allTasks</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=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">getById</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> ({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">params</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><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 class=\"mtk12\">params</span><span class=\"mtk1\">:{</span><span class=\"mtk12\">taskId</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\">response</span><span class=\"mtk1\">:</span><span class=\"mtk10\">any</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }) </span><span class=\"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\">taskId</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">params</span><span class=\"mtk1\">.</span><span class=\"mtk12\">taskId</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\">task</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">tasks</span><span class=\"mtk1\">.</span><span class=\"mtk11\">findOne</span><span class=\"mtk1\">({</span><span class=\"mtk12\">_id:</span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">ObjectId</span><span class=\"mtk1\">(</span><span class=\"mtk12\">taskId</span><span class=\"mtk1\">)});</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\">(!</span><span class=\"mtk12\">task</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">`no task with Id: </span><span class=\"mtk4\">${</span><span class=\"mtk12\">taskId</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=\"mtk15\">return</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">200</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span><span class=\"mtk12\">task:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">task</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">updateById</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> ({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">params</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">request</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">response</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}:{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">params</span><span class=\"mtk1\">:{</span><span class=\"mtk12\">taskId</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\">request</span><span class=\"mtk1\">:</span><span class=\"mtk10\">any</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">response</span><span class=\"mtk1\">:</span><span class=\"mtk10\">any</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}) </span><span class=\"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\">taskId</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">params</span><span class=\"mtk1\">.</span><span class=\"mtk12\">taskId</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\">name</span><span class=\"mtk1\">, </span><span class=\"mtk12\">isCompleted</span><span class=\"mtk1\">} = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">request</span><span class=\"mtk1\">.</span><span class=\"mtk11\">body</span><span class=\"mtk1\">().</span><span class=\"mtk12\">value</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">task</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">tasks</span><span class=\"mtk1\">.</span><span class=\"mtk11\">updateOne</span><span class=\"mtk1\">({</span><span class=\"mtk12\">_id:</span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">ObjectId</span><span class=\"mtk1\">(</span><span class=\"mtk12\">taskId</span><span class=\"mtk1\">)},</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span><span class=\"mtk12\">$set:</span><span class=\"mtk1\">{</span><span class=\"mtk12\">name:name</span><span class=\"mtk1\">, </span><span class=\"mtk12\">isCompleted:isCompleted</span><span class=\"mtk1\">}});</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">200</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span><span class=\"mtk12\">message:</span><span class=\"mtk8\">&quot;Updated task&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">task:task</span><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">deleteTask</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> ({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">params</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">response</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\">params</span><span class=\"mtk1\">:{</span><span class=\"mtk12\">taskId</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\">response</span><span class=\"mtk1\">:</span><span class=\"mtk10\">any</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}) </span><span class=\"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\">taskId</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">params</span><span class=\"mtk1\">.</span><span class=\"mtk12\">taskId</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\">task</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">tasks</span><span class=\"mtk1\">.</span><span class=\"mtk11\">deleteOne</span><span class=\"mtk1\">({</span><span class=\"mtk12\">_id:</span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">ObjectId</span><span class=\"mtk1\">(</span><span class=\"mtk12\">taskId</span><span class=\"mtk1\">)});</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">200</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span><span class=\"mtk12\">message:</span><span class=\"mtk8\">&quot;Deleted task&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">task:task</span><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span></code></pre>\n<p>With that out of the way, you need to create your todo CRUD routes. So, head over to <code>allRoutes.ts</code> and import the CRUD functions from the task controllers, then create the routes for our todo, as follows.</p>\n<p><code>routes.allRoutes.ts</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"13\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Router</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/x/oak/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span><span class=\"mtk12\">signup</span><span class=\"mtk1\">, </span><span class=\"mtk12\">signin</span><span class=\"mtk1\">} </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../controllers/users.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span><span class=\"mtk12\">create</span><span class=\"mtk1\">, </span><span class=\"mtk12\">getTasks</span><span class=\"mtk1\">, </span><span class=\"mtk12\">getById</span><span class=\"mtk1\">, </span><span class=\"mtk12\">updateById</span><span class=\"mtk1\">, </span><span class=\"mtk12\">deleteTask</span><span class=\"mtk1\">} </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../controllers/tasks.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Router</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//User routes</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/api/signup&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">signup</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\">&quot;/api/signin&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">signin</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//Task routes</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/api/tasks&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">create</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\">&quot;/api/tasks&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">getTasks</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\">&quot;/api/tasks/:taskId&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">getById</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      .</span><span class=\"mtk11\">patch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/api/tasks/:taskId&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">updateById</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      .</span><span class=\"mtk11\">delete</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/api/tasks/:taskId&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">deleteTask</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\">;</span></span></code></pre>\n<h2 id=\"protect-todo-routes\" style=\"position:relative;\"><a href=\"#protect-todo-routes\" aria-label=\"protect todo routes permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Protect Todo Routes</h2>\n<p>You need to protect your todo routes so that an unauthorized person will not be able to access them.</p>\n<p>To protect the todo routes, go to your <code>middlewares</code> folder: create a file called <code>isAuthorized.ts</code>, import the <code>verify</code> function from deno JWT URL, import <code>Context</code> from deno, import the secret key you've created, and create the <code>authorized</code> function.</p>\n<p>The authorize function checks if a user has a JWT token, grant the user access if he does, and deny him access if otherwise.</p>\n<p><code>middlewares.isAuthorized.ts</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"14\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">verify</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/x/djwt@v2.4/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">key</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../utils/apiKey.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Context</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/x/oak/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">authourized</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">ctx</span><span class=\"mtk1\">: </span><span class=\"mtk10\">Context</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">:</span><span class=\"mtk10\">any</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">try</span><span class=\"mtk1\">{   </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">headers</span><span class=\"mtk1\">: </span><span class=\"mtk10\">Headers</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">ctx</span><span class=\"mtk1\">.</span><span class=\"mtk12\">request</span><span class=\"mtk1\">.</span><span class=\"mtk12\">headers</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\">authorization</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">headers</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</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=\"mtk15\">if</span><span class=\"mtk1\">(!</span><span class=\"mtk12\">authorization</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">ctx</span><span class=\"mtk1\">.</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">401</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">authorization</span><span class=\"mtk1\">.</span><span class=\"mtk11\">split</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39; &#39;</span><span class=\"mtk1\">)[</span><span class=\"mtk7\">1</span><span class=\"mtk1\">];</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\">(!</span><span class=\"mtk12\">jwt</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">ctx</span><span class=\"mtk1\">.</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">401</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">payload</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">verify</span><span class=\"mtk1\">(</span><span class=\"mtk12\">jwt</span><span class=\"mtk1\">, </span><span class=\"mtk12\">key</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\">(!</span><span class=\"mtk12\">payload</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\">Error</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;!payload&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">next</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     } </span><span class=\"mtk15\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">ctx</span><span class=\"mtk1\">.</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">401</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">ctx</span><span class=\"mtk1\">.</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> ={</span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;You are not authorized to access this route&quot;</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span></code></pre>\n<p>To protect your todo routes, import the authorized middleware function from the <code>isAuthorized.ts</code> middleware file and pass the middleware into the todo routes to protect them from unauthorized people.</p>\n<p><code>routes.allRoutes.ts</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"15\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Router</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/x/oak/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span><span class=\"mtk12\">signup</span><span class=\"mtk1\">, </span><span class=\"mtk12\">signin</span><span class=\"mtk1\">} </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../controllers/users.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span><span class=\"mtk12\">create</span><span class=\"mtk1\">, </span><span class=\"mtk12\">getTasks</span><span class=\"mtk1\">, </span><span class=\"mtk12\">getById</span><span class=\"mtk1\">, </span><span class=\"mtk12\">updateById</span><span class=\"mtk1\">, </span><span class=\"mtk12\">deleteTask</span><span class=\"mtk1\">} </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../controllers/tasks.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">authourized</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../middlewares/isAuthorized.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Router</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//User routes</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/api/signup&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">signup</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\">&quot;/api/signin&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">signin</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//Task routes</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/api/tasks&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">authourized</span><span class=\"mtk1\">, </span><span class=\"mtk12\">create</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\">&quot;/api/tasks&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">authourized</span><span class=\"mtk1\">, </span><span class=\"mtk12\">getTasks</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\">&quot;/api/tasks/:taskId&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">authourized</span><span class=\"mtk1\">, </span><span class=\"mtk12\">getById</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      .</span><span class=\"mtk11\">patch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/api/tasks/:taskId&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">authourized</span><span class=\"mtk1\">, </span><span class=\"mtk12\">updateById</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      .</span><span class=\"mtk11\">delete</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/api/tasks/:taskId&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">authourized</span><span class=\"mtk1\">, </span><span class=\"mtk12\">deleteTask</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\">;</span></span></code></pre>\n<p>Awesome! Your application is ready, but wait! Don't get too excited yet, relax let's test the application :)</p>\n<p>Below is what your final project directory looks like:</p>\n<p><code>DenoAPI_JWT_Auth</code>  </p>\n<p>│<br>\n└─<strong>src</strong><br>\n│   └───controllers<br>\n│   │      └───users.ts<br>\n│   │      └───tasks.ts<br>\n│   │\n│   └───database<br>\n│   │      └───connectDB.ts<br>\n│   │<br>\n│   └───middlewares<br>\n│   │      └───isAuthorized.ts<br>\n│   │<br>\n│   └───routes<br>\n│   │      └───allRoutes.ts<br>\n│   │\n│   └───schema<br>\n│   │      └───user.ts<br>\n│   │      └───task.ts<br>\n│   │\n│   └───utils<br>\n│   │      └───apiKey.ts<br>\n│   │<br>\n└─<strong>app.ts</strong>  </p>\n<h2 id=\"test-application\" style=\"position:relative;\"><a href=\"#test-application\" aria-label=\"test application permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test Application</h2>\n<p>Now that your application is ready, you need to test the various routes to ensure they are working. To test the routes, rerun your server with <code>deno run --allow-net app.ts</code>.</p>\n<p><img src=\"/62ae9cc872cb4e6726bf38887a6f95f2/apk23wt.webp\" alt=\"deno run screenshot\"></p>\n<p>Great! The app is running on port:8080. You can now head to the postman to test your routes.</p>\n<h3 id=\"signup-route\" style=\"position:relative;\"><a href=\"#signup-route\" aria-label=\"signup route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Signup Route</h3>\n<p><img src=\"/2737369979374f3a18b07747fbc29495/d2orbz0.webp\" alt=\"Sign up\"></p>\n<p><img src=\"/d122648378e66a04ba9f5ccea186d791/trydtxn.webp\"></p>\n<h3 id=\"sign-in-route\" style=\"position:relative;\"><a href=\"#sign-in-route\" aria-label=\"sign in route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Sign-in Route</h3>\n<p><img src=\"/6c3a13c7403199d459243429bd206718/fee5d0s.webp\" alt=\"Signin Route URL\"></p>\n<p><img src=\"/76e7addc166b0dfbc834423b2f8c664f/wncqtya.webp\" alt=\"Signin Route\"></p>\n<p>Amazing! Now that you have signed up and authenticated a user, the returned token, which shows that the user has been authenticated, can be used to access your todo CRUD APIs.</p>\n<h3 id=\"accessing-the-todo-routes\" style=\"position:relative;\"><a href=\"#accessing-the-todo-routes\" aria-label=\"accessing the todo 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>Accessing the Todo Routes</h3>\n<p>First, let's try accessing your todo routes without the token...</p>\n<h4 id=\"create-task-route\" style=\"position:relative;\"><a href=\"#create-task-route\" aria-label=\"create task route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create Task Route</h4>\n<p><img src=\"/ecc4bd696513d61205cf9a4330f631ed/0bohcxv.webp\" alt=\"Create Task Route URL\">  </p>\n<p><img src=\"/821f749c0ad4c42017623a3bce8034d2/q6eetmg.webp\" alt=\"Create Task Route Access Denied\"></p>\n<p>As you can see, when you tried to create a task, you got a message <code>You are not authorized to access this route</code> because a random person did it without a token.</p>\n<p>Now, let's also try accessing the delete by Id route without the token...</p>\n<h4 id=\"delete-task-route\" style=\"position:relative;\"><a href=\"#delete-task-route\" aria-label=\"delete task route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Delete Task Route</h4>\n<p><img src=\"/3c361eebddb2e01593ae8bbde40dbce6/ngozekb.webp\" alt=\"Delete Task Route URL\"></p>\n<p><img src=\"/1490faa5e0338c8995b8f22555595236/cdkr6ad.webp\" alt=\"Delete Task Route Access Denied\"></p>\n<p>Your todo CRUD APIs have been protected, and the only way a user can access them is by getting authenticated. Now let's log in again and use the returned token to access the todo routes.</p>\n<p><img src=\"/540a044d27006d91a86d4db1928b0c73/ehp4zwf.webp\" alt=\"Tasks\"></p>\n<p>So, you have logged a user in and put the returned Bearer's token in the authorization header. You can access our todo APIs now because, with the bearer's token, you are authorized to access the todo APIs.</p>\n<h4 id=\"create-task-route-1\" style=\"position:relative;\"><a href=\"#create-task-route-1\" aria-label=\"create task route 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>Create Task Route</h4>\n<p><img src=\"/ecc4bd696513d61205cf9a4330f631ed/y9ilrk9.webp\" alt=\"Create Task Route URL\"></p>\n<p><img src=\"/0592e46a3e4261079c741e095e5a987e/nbiaskx.webp\" alt=\"Create Task Route Access Granted\"></p>\n<h4 id=\"get-all-tasks-route\" style=\"position:relative;\"><a href=\"#get-all-tasks-route\" aria-label=\"get all tasks route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Get All Tasks Route</h4>\n<p><img src=\"/990cf69f38c62c2d8e240d8f30d49ef8/zosrr9u.webp\" alt=\"Get All Tasks Route\"></p>\n<p><img src=\"/12178b6a0d02f0b42eb81d6d4c8be97b/zxkgmsm.webp\" alt=\"Get All Tasks Route Access Granted\"></p>\n<h4 id=\"get-task-by-id-route\" style=\"position:relative;\"><a href=\"#get-task-by-id-route\" aria-label=\"get task by id route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Get Task By Id Route</h4>\n<p><img src=\"/3c361eebddb2e01593ae8bbde40dbce6/hph0xmy.webp\" alt=\"Get Task By Id Route\"></p>\n<p><img src=\"/a1856e78c8c2916792aefec9834c48f7/get-task-by-id.webp\" alt=\"Get Task By Id Route Access Granted\"></p>\n<p>Feel free to test the other routes to see how things work.</p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>In this tutorial, you've built a todo CRUD API and protected the routes from unauthorized access using JSON Web Token (JWT). You have learned how to create an Oak server in Deno, connect MongoDB, implement JWT authentication, as well as create and authenticate CRUD routes in a Deno application. </p>\n<p><a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/Deno/denoAPI_JWT_Auth\">The code for this tutorial is available here</a> on Github. Feel free to clone and extend the features of the application.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n</style>","frontmatter":{"date":"July 28, 2022","updated_date":null,"title":"How to Implement JWT Authentication for CRUD APIs in Deno","tags":["JWT","Deno","Authentication"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/ecb7a333dd6ee8ea03a2f5cc6c9633c2/58556/jwt-authentication-with-deno.webp","srcSet":"/static/ecb7a333dd6ee8ea03a2f5cc6c9633c2/61e93/jwt-authentication-with-deno.webp 200w,\n/static/ecb7a333dd6ee8ea03a2f5cc6c9633c2/1f5c5/jwt-authentication-with-deno.webp 400w,\n/static/ecb7a333dd6ee8ea03a2f5cc6c9633c2/58556/jwt-authentication-with-deno.webp 800w,\n/static/ecb7a333dd6ee8ea03a2f5cc6c9633c2/99238/jwt-authentication-with-deno.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Ekekenta Odionyenfe Clinton","github":"icode247","avatar":null}}}},{"node":{"fields":{"slug":"/engineering/guest-post/loopback-rest-api-authentication/"},"html":"<p>Authentication and authorization are critical in every software application to secure user data and allow access to trusted users. In some cases, implementing authentication and authorization is not an easy process.</p>\n<p>However, LoopBack 4 offers an authentication package <strong>@loopback/authentication</strong> that helps secure your application's API endpoints. It provides custom authentication strategies and a <strong>@authenticate</strong> decorator that requires minimal boilerplate code.</p>\n<h2 id=\"what-is-loopback\" style=\"position:relative;\"><a href=\"#what-is-loopback\" aria-label=\"what is loopback permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is LoopBack?</h2>\n<p>According to the <a href=\"https://loopback.io/doc/en/lb4/index.html\">LoopBack 4 documentation</a>:</p>\n<blockquote>\n<p>LoopBack is a flexible, open source Node.js and TypeScript framework built on Express. It helps you quickly develop APIs and microservices built on backend systems such as databases and SOAP or REST services.</p>\n</blockquote>\n<p>Loopback provides several features that allow you to build your application with less boilerplate code.</p>\n<h2 id=\"what-is-json-web-token-jwt\" style=\"position:relative;\"><a href=\"#what-is-json-web-token-jwt\" aria-label=\"what is json web token jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is JSON Web Token (JWT)?</h2>\n<p>JSON Web Token (JWT) is an open standard <a href=\"https://datatracker.ietf.org/doc/html/rfc7519.html\">defined by Internet Engineering Task Force (IETF) in RFC 7519</a>.</p>\n<p>It is a standard used for securely transferring claims between two parties over the internet. It uses JSON Web Signature (JWS) for the secure transfer of claims and eliminates the possibility of tampering. Accordingly, JWTs can be signed with either a secret (HMAC technique) or a public/private key pair (RSA or ECDSA).</p>\n<p>In simple words, it is used for authentication and secure information sharing. A JWT token is made up of three components that are separated by three dots:</p>\n<ul>\n<li><strong>Header:</strong> The header is made up of two parts — the kind of token, which is JWT; the signature technique used, either HMAC SHA256 or RSA.</li>\n<li><strong>Payload:</strong> The payload is the token, which includes the claims. Claims are assertions about an entity that provides extra information.</li>\n<li><strong>Signature:</strong> The encoded header, encoded payload, a secret, and the algorithm provided in the header comprise the signature.</li>\n</ul>\n<blockquote>\n<p>You can learn more about <a href=\"https://www.loginradius.com/blog/engineering/guest-post/jwt-authentication-best-practices-and-when-to-use/\">JWT and its best practices here</a>.</p>\n</blockquote>\n<h2 id=\"prerequisites\" style=\"position:relative;\"><a href=\"#prerequisites\" aria-label=\"prerequisites permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Prerequisites</h2>\n<p>This tutorial is a hands-on demonstration. To follow along, be sure you have the following in place:</p>\n<ul>\n<li>A Linux machine — This tutorial will use Ubuntu 20.04.3 LTS (Focal Fossa). The tutorial also works well on other Linux distributions and operating systems.</li>\n<li><a href=\"https://nodejs.org/\"><strong>NodeJS</strong></a> — JavaScript runtime built on Chrome's V8 JavaScript engine.</li>\n<li><a href=\"https://www.mongodb.com/\"><strong>MongoDB</strong></a> — Document-oriented database program.</li>\n</ul>\n<h2 id=\"install-loopback-cli\" style=\"position:relative;\"><a href=\"#install-loopback-cli\" aria-label=\"install loopback cli permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Install LoopBack CLI</h2>\n<p>To start building your LoopBack REST API, first install LoopBack CLI, which provides the quickest method to create a LoopBack 4 project that follows best practices.</p>\n<p>Use the command below to install the Loopback CLI globally:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">npm i -g @loopback/cli</span></span></code></pre>\n<p>You can grab a cup of coffee while you wait for the installation to complete. Then open your command line, create an <code>AuthWithLooback</code> folder, and change the directory to the <code>AuthWithLooback</code> folder with commands below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">mkdir AuthWithLooback</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">cd</span><span class=\"mtk1\"> AuthWithLooback</span></span></code></pre>\n<h2 id=\"scaffold-your-loopback-project\" style=\"position:relative;\"><a href=\"#scaffold-your-loopback-project\" aria-label=\"scaffold your loopback project permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Scaffold Your LoopBack Project</h2>\n<p>So, you've installed Loopback CLI and created a project directory. Let's run the following command to create a LoopBack project:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">lb4 app</span></span></code></pre>\n<p>Select the options as in the following screenshot to complete the prompts.</p>\n<p><img src=\"/982c31e4e0a8b99735b9e920e72e898f/l5wg0nTQ.webp\" alt=\"Creating a loopback project\"></p>\n<p>After completing the prompts, LoopBack will configure the TypeScript compiler and install all the required dependencies. Change directory to the <code>auth-with-loopback</code> folder.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">cd</span><span class=\"mtk1\"> auth-with-loopback</span></span></code></pre>\n<h2 id=\"create-a-model\" style=\"position:relative;\"><a href=\"#create-a-model\" aria-label=\"create a model permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create a Model</h2>\n<p>You've successfully created your Loopback application. Now, let’s create a Model to store the news details with the command below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">lb4 model</span></span></code></pre>\n<p>Select the options as in the following screenshot to complete the prompts.</p>\n<p><img src=\"/3f73bef6f5422b16cc466d5f279701a9/lSCGXHs.webp\" alt=\"Creating a News Model\"></p>\n<p>After the <code>date_created</code> property definition, press the enter key to exit the prompt.</p>\n<p>Loopback will create a <code>NewsModel</code> file in the <code>src/models</code> — the folder where <code>NewsModel</code> will be defined.</p>\n<p>Next, you need to create a data source to connect to your preferred database. For demonstration, this tutorial connects to a MongoDB database.</p>\n<p>Run the following command in your terminal to create a data source:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">  lb4 datasource</span></span></code></pre>\n<p>Select the options as in the following screenshot to complete the prompts.</p>\n<p><img src=\"/aa8582e5de5c7011c46a43242342a5d2/pHvPgEQA.webp\" alt=\"Creating News datasource\"></p>\n<p>After completing the prompts, LoopBack will create the <code>News</code> file in the <code>src/datasource</code> folder.</p>\n<p>Then, create a <a href=\"https://loopback.io/doc/en/lb4/Repository.html\">Repository</a> for CRUD operations of your NewModel with the command below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">lb4 repository</span></span></code></pre>\n<p>After completing the prompts, LoopBack will create the <code>NewsModelRepository</code> file in the <code>src/repository</code> folder.</p>\n<p>Select <code>NewsDatasource</code> as the data source, <code>NewsModel</code> as the model for generating the repository, and <code>DefaultCrudRepository</code> as the base repository class.</p>\n<p>Your selection for the prompts shall look like the screenshot below.</p>\n<p><img src=\"/7789349e93d10cfc0800e4f822e581ca/WWH5tYJQ.webp\" alt=\"Creating News Repository\"></p>\n<p>After completing the prompts, LoopBack will create the <code>NewsModelRepository</code> file in the <code>src/repository</code> folder.</p>\n<p>Lastly, create a controller for the <code>NewsModel</code> you created with the command below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">  lb4 controller</span></span></code></pre>\n<p>Your selection for the prompts should look like the screenshot below.</p>\n<p><img src=\"/a22f45625db4bd560279a422e127665f/iHD6lPCg.webp\" alt=\"Creating News Controller\"></p>\n<p>After completing the prompts, LoopBack will create the <code>NewsController</code> file in the <code>src/controller</code> folder. So far, your project structure, omitting the <code>node_modules</code> folder, should look as follows.</p>\n<p>📦auth-with-loopback<br>\n┣ 📂public<br>\n┃ ┗ 📜index.html<br>\n┣ 📂src<br>\n┃ ┣ 📂<strong>tests</strong><br>\n┃ ┃ ┣ 📂acceptance<br>\n┃ ┃ ┃ ┣ 📜home-page.acceptance.ts<br>\n┃ ┃ ┃ ┣ 📜ping.controller.acceptance.ts<br>\n┃ ┃ ┃ ┗ 📜test-helper.ts<br>\n┃ ┃ ┗ 📜README.md<br>\n┃ ┣ 📂controllers<br>\n┃ ┃ ┣ 📜README.md<br>\n┃ ┃ ┣ 📜index.ts<br>\n┃ ┃ ┣ 📜news-controller.controller.ts<br>\n┃ ┃ ┗ 📜ping.controller.ts<br>\n┃ ┣ 📂datasources<br>\n┃ ┃ ┣ 📜README.md<br>\n┃ ┃ ┣ 📜index.ts<br>\n┃ ┃ ┗ 📜news.datasource.ts<br>\n┃ ┣ 📂models<br>\n┃ ┃ ┣ 📜README.md<br>\n┃ ┃ ┣ 📜index.ts<br>\n┃ ┃ ┗ 📜news-model.model.ts<br>\n┃ ┣ 📂repositories<br>\n┃ ┃ ┣ 📜README.md<br>\n┃ ┃ ┣ 📜index.ts<br>\n┃ ┃ ┗ 📜news-model.repository.ts<br>\n┃ ┣ 📜application.ts<br>\n┃ ┣ 📜index.ts<br>\n┃ ┣ 📜migrate.ts<br>\n┃ ┣ 📜openapi-spec.ts<br>\n┃ ┗ 📜sequence.ts<br>\n┣ 📜.dockerignore<br>\n┣ 📜.eslintignore<br>\n┣ 📜.eslintrc.js<br>\n┣ 📜.gitignore<br>\n┣ 📜.mocharc.json<br>\n┣ 📜.prettierignore<br>\n┣ 📜.prettierrc<br>\n┣ 📜.yo-rc.json<br>\n┣ 📜DEVELOPING.md<br>\n┣ 📜Dockerfile<br>\n┣ 📜README.md<br>\n┣ 📜package-lock.json<br>\n┣ 📜package.json<br>\n┗ 📜tsconfig.json</p>\n<h2 id=\"add-custom-data\" style=\"position:relative;\"><a href=\"#add-custom-data\" aria-label=\"add custom data permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Add Custom Data</h2>\n<p>Now that you have the Model setup, run the server, and add some custom data to the News collection in MongoDB.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">#start the server</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    npm run start</span></span></code></pre>\n<p>The above command will start the TypeScript compiler, which will build the project and check for possible errors. If everything goes well with the code, you should see the output on the terminal, as follows:</p>\n<p><img src=\"/cf1c4681ababa5101284b580193e8bf3/lSCGXHnw.webp\" alt=\"Starting LoopBack Server\"></p>\n<p>Next, open your favorite browser and navigate to <code>http://localhost:3000</code>. You should see an output as follows:</p>\n<p><img src=\"/321018f4c7be6074ce493ab2f711a5c2/hL9y8IIg.webp\" alt=\"LoopBack API Dashboard\"></p>\n<p>Now, click on the explorer link, where you can make requests to your LoopBack application. On the explorer page, locate the post endpoint and add some custom data to the news collection by clicking the <code>try it out</code> button with the data below on the request body.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"json\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">&quot;title&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Upgrade to Loopback V4&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">&quot;body&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;The developers of Loopback urges the V3 users to upgrade to V4 as soon as possible&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">&quot;date_created&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;2021-12-14T00:57:43.197Z&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Then, click the <code>execute</code> button to run the query.</p>\n<p><img src=\"/905e332f7af326f984c298c9a6239c41/jiC_1P0A.webp\" alt=\"Executing Queries\"></p>\n<p>You can add as many records as you like to experiment with the endpoints. The important thing to note here is that the endpoints are not protected. Anyone may create, read, update, and delete records.</p>\n<p>In a moment, this tutorial explains how to secure the endpoints so that only logged-in users can access them.</p>\n<p>To begin, install LoopBack <code>authentication</code> and <code>authentication-jwt</code>, as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">  npm i --save @loopback/authentication @loopback/authentication-jwt</span></span></code></pre>\n<h2 id=\"setup-authentication-components\" style=\"position:relative;\"><a href=\"#setup-authentication-components\" aria-label=\"setup authentication components permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Setup Authentication Components</h2>\n<p>To protect the application, you'll implement user authentication and authorization, which implies that only logged-in users will be able to access your APIs. You'll create two endpoints in the User controller:</p>\n<ul>\n<li><code>/Signup</code> endpoint: To handle user’s sign up.</li>\n<li><code>/Login</code> endpoint: To handle user’s login.</li>\n</ul>\n<h3 id=\"create-your-signup-endpoint\" style=\"position:relative;\"><a href=\"#create-your-signup-endpoint\" aria-label=\"create your signup endpoint permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create Your Signup Endpoint</h3>\n<p>You’ll start with the signup controller to enable users to create an account. Create an empty controller with the command below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    lb4 controller</span></span></code></pre>\n<p>Your selection for the prompts should be as follows:</p>\n<p><img src=\"/c0653ec5c8a0f68a48e55ff2159137d4/6LCgT-Gw.webp\" alt=\"Creating User Controller\"></p>\n<p>Then, open the <code>src/controllers/user.controller.ts</code> file, and import the required modules with the following code snippet:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"12\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">authenticate</span><span class=\"mtk1\">, </span><span class=\"mtk12\">TokenService</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@loopback/authentication&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Credentials</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">MyUserService</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">TokenServiceBindings</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">User</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">UserRepository</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">UserServiceBindings</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@loopback/authentication-jwt&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">inject</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@loopback/core&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">model</span><span class=\"mtk1\">, </span><span class=\"mtk12\">property</span><span class=\"mtk1\">, </span><span class=\"mtk12\">repository</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@loopback/repository&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">get</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">getModelSchemaRef</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">post</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">requestBody</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">SchemaObject</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@loopback/rest&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">SecurityBindings</span><span class=\"mtk1\">, </span><span class=\"mtk12\">securityId</span><span class=\"mtk1\">, </span><span class=\"mtk12\">UserProfile</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@loopback/security&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">genSalt</span><span class=\"mtk1\">, </span><span class=\"mtk12\">hash</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;bcryptjs&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">_</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;lodash&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ........</span></span></code></pre>\n<p>Next, set up your user credential objects, and verify the user credentials using the <code>UserService</code>, injecting <code>MyUserService</code> into the <code>authentication-jwt</code> extension.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"13\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    @</span><span class=\"mtk11\">model</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">CreateUser</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">User</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">property</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;string&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">required:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">password</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">UserSchema</span><span class=\"mtk1\">: </span><span class=\"mtk10\">SchemaObject</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;object&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">required:</span><span class=\"mtk1\"> [</span><span class=\"mtk8\">&#39;email&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;password&#39;</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">properties:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">email:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;string&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">format:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;email&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;string&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">minLength:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">6</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">RequestBody</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">description:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;The input of login function&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">required:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">content:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">schema:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">UserSchema</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">UserController</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        @</span><span class=\"mtk11\">inject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">TokenServiceBindings</span><span class=\"mtk1\">.</span><span class=\"mtk12\">TOKEN_SERVICE</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jwtService</span><span class=\"mtk1\">: </span><span class=\"mtk10\">TokenService</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        @</span><span class=\"mtk11\">inject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">UserServiceBindings</span><span class=\"mtk1\">.</span><span class=\"mtk12\">USER_SERVICE</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk12\">userService</span><span class=\"mtk1\">: </span><span class=\"mtk10\">MyUserService</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        @</span><span class=\"mtk11\">inject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">SecurityBindings</span><span class=\"mtk1\">.</span><span class=\"mtk12\">USER</span><span class=\"mtk1\">, { </span><span class=\"mtk12\">optional:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UserProfile</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        @</span><span class=\"mtk11\">repository</span><span class=\"mtk1\">(</span><span class=\"mtk12\">UserRepository</span><span class=\"mtk1\">) </span><span class=\"mtk4\">protected</span><span class=\"mtk1\"> </span><span class=\"mtk12\">userRepository</span><span class=\"mtk1\">: </span><span class=\"mtk10\">UserRepository</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      ) { }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ..........</span></span></code></pre>\n<p>Finally, you'll build your signup endpoint, which will listen to POST requests. Here, you shall save the hashed version of the user's password in the database to keep it safe.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"14\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">     @</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/signup&#39;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">responses:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&#39;200&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">description:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;User&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">content:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">schema:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&#39;x-ts-type&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">signUp</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">requestBody</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">content:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">schema:</span><span class=\"mtk1\"> </span><span class=\"mtk11\">getModelSchemaRef</span><span class=\"mtk1\">(</span><span class=\"mtk12\">CreateUser</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">title:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;NewUser&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">newUserRequest</span><span class=\"mtk1\">: </span><span class=\"mtk12\">CreateUser</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ): </span><span class=\"mtk10\">Promise</span><span class=\"mtk1\">&lt;</span><span class=\"mtk12\">User</span><span class=\"mtk1\">&gt; {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">hash</span><span class=\"mtk1\">(</span><span class=\"mtk12\">newUserRequest</span><span class=\"mtk1\">.</span><span class=\"mtk12\">password</span><span class=\"mtk1\">, </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">genSalt</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const </span><span class=\"mtk12\">savedUser</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">userRepository</span><span class=\"mtk1\">.</span><span class=\"mtk11\">create</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">_</span><span class=\"mtk1\">.</span><span class=\"mtk11\">omit</span><span class=\"mtk1\">(</span><span class=\"mtk12\">newUserRequest</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;password&#39;</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      );</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      await this.userRepository.userCredentials(savedUser.id).create({ </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> });</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">savedUser</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .........</span></span></code></pre>\n<h3 id=\"create-your-login-controller\" style=\"position:relative;\"><a href=\"#create-your-login-controller\" aria-label=\"create your login controller permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create Your Login Controller</h3>\n<p>Now that you've set up the signup endpoint, create the login endpoint so that registered users may log in to the API.</p>\n<p>Using the code snippet below, set up the login route in the <code>src/controllers/user.controller.ts</code> file. In the event of a successful log-in, a token is sent to the user.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"15\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/signin&#39;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">responses:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&#39;200&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">description:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;Token&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">content:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">schema:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;object&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">properties:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                  </span><span class=\"mtk12\">token:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;string&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">signIn</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">requestBody</span><span class=\"mtk1\">(</span><span class=\"mtk12\">RequestBody</span><span class=\"mtk1\">) </span><span class=\"mtk12\">credentials</span><span class=\"mtk1\">: </span><span class=\"mtk12\">Credentials</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ): </span><span class=\"mtk10\">Promise</span><span class=\"mtk1\">&lt;{ token: </span><span class=\"mtk12\">string</span><span class=\"mtk1\"> }&gt; {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">userService</span><span class=\"mtk1\">.</span><span class=\"mtk11\">verifyCredentials</span><span class=\"mtk1\">(</span><span class=\"mtk12\">credentials</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const </span><span class=\"mtk12\">userProfile</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">userService</span><span class=\"mtk1\">.</span><span class=\"mtk11\">convertToUserProfile</span><span class=\"mtk1\">(</span><span class=\"mtk12\">user</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const </span><span class=\"mtk12\">token</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">jwtService</span><span class=\"mtk1\">.</span><span class=\"mtk11\">generateToken</span><span class=\"mtk1\">(</span><span class=\"mtk12\">userProfile</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      return { </span><span class=\"mtk12\">token</span><span class=\"mtk1\"> };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span></code></pre>\n<p>Perhaps, you can show the currently logged-in user by adding a <code>/whoami</code> endpoint.</p>\n<p>In the <code>src/controllers/user.controller.ts</code> file, get the details of the currently logged-in user using the code snippet below. Users should access this endpoint only when they are logged in.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"16\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">authenticate</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;jwt&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/whoami&#39;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">responses:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk8\">&#39;200&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">description:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;Return current user&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">content:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">schema:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                  </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;string&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">whoAmI</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        @</span><span class=\"mtk11\">inject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">SecurityBindings</span><span class=\"mtk1\">.</span><span class=\"mtk12\">USER</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">loggedInUserProfile</span><span class=\"mtk1\">: </span><span class=\"mtk12\">UserProfile</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      ): </span><span class=\"mtk10\">Promise</span><span class=\"mtk1\">&lt;</span><span class=\"mtk12\">string</span><span class=\"mtk1\">&gt; {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        return loggedInUserProfile</span><span class=\"mtk12\">[securityId];</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">      }</span></span></code></pre>\n<p>Now, open <code>src/application.ts</code> and bind the authentication components to your application class. First, import Loopback <code>AuthenticationComponent</code>, <code>JWTAuthenticationComponent</code>, and <code>NewsDataSource</code> from your <code>datasources</code> using the following code snippet:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"17\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">//...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">AuthenticationComponent</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@loopback/authentication&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">JWTAuthenticationComponent</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">UserServiceBindings</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">} </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@loopback/authentication-jwt&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">NewsDataSource</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./datasources&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//...</span></span></code></pre>\n<p>Then, mount the jwt authentication system and bind your <code>NewsDataSource</code> to the <code>UserService</code> data source.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"18\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">//...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// ------ ADD SNIPPET INSIDE THE CONTRUCTOR BLOCK ---------</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">component</span><span class=\"mtk1\">(</span><span class=\"mtk12\">AuthenticationComponent</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">component</span><span class=\"mtk1\">(</span><span class=\"mtk12\">JWTAuthenticationComponent</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">dataSource</span><span class=\"mtk1\">(</span><span class=\"mtk12\">NewsDataSource</span><span class=\"mtk1\">, </span><span class=\"mtk12\">UserServiceBindings</span><span class=\"mtk1\">.</span><span class=\"mtk12\">DATASOURCE_NAME</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//...</span></span></code></pre>\n<p>Finally, add the authenticate action in the Sequence. Also, modify the error when authentication fails to return status code 401 (Unauthorized). Open the <code>src/sequence.ts</code> file and add the code snippet below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"19\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">FindRoute</span><span class=\"mtk1\">, </span><span class=\"mtk12\">InvokeMethod</span><span class=\"mtk1\">, </span><span class=\"mtk12\">MiddlewareSequence</span><span class=\"mtk1\">, </span><span class=\"mtk12\">ParseParams</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Reject</span><span class=\"mtk1\">, </span><span class=\"mtk12\">RequestContext</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Send</span><span class=\"mtk1\">, </span><span class=\"mtk12\">SequenceActions</span><span class=\"mtk1\">, </span><span class=\"mtk12\">SequenceHandler</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@loopback/rest&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">AuthenticateFn</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">AuthenticationBindings</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">AUTHENTICATION_STRATEGY_NOT_FOUND</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">USER_PROFILE_NOT_FOUND</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;@loopback/authentication&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">inject</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@loopback/core&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">MySequence</span><span class=\"mtk1\"> </span><span class=\"mtk4\">implements</span><span class=\"mtk1\"> </span><span class=\"mtk10\">SequenceHandler</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            @</span><span class=\"mtk11\">inject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">SequenceActions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">FIND_ROUTE</span><span class=\"mtk1\">) </span><span class=\"mtk4\">protected</span><span class=\"mtk1\"> </span><span class=\"mtk12\">findRoute</span><span class=\"mtk1\">: </span><span class=\"mtk10\">FindRoute</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            @</span><span class=\"mtk11\">inject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">SequenceActions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">PARSE_PARAMS</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">protected</span><span class=\"mtk1\"> </span><span class=\"mtk12\">parseParams</span><span class=\"mtk1\">: </span><span class=\"mtk10\">ParseParams</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            @</span><span class=\"mtk11\">inject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">SequenceActions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">INVOKE_METHOD</span><span class=\"mtk1\">) </span><span class=\"mtk4\">protected</span><span class=\"mtk1\"> </span><span class=\"mtk12\">invoke</span><span class=\"mtk1\">: </span><span class=\"mtk10\">InvokeMethod</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            @</span><span class=\"mtk11\">inject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">SequenceActions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">SEND</span><span class=\"mtk1\">) </span><span class=\"mtk4\">protected</span><span class=\"mtk1\"> </span><span class=\"mtk12\">send</span><span class=\"mtk1\">: </span><span class=\"mtk10\">Send</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            @</span><span class=\"mtk11\">inject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">SequenceActions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">REJECT</span><span class=\"mtk1\">) </span><span class=\"mtk4\">protected</span><span class=\"mtk1\"> </span><span class=\"mtk12\">reject</span><span class=\"mtk1\">: </span><span class=\"mtk10\">Reject</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            @</span><span class=\"mtk11\">inject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">AuthenticationBindings</span><span class=\"mtk1\">.</span><span class=\"mtk12\">AUTH_ACTION</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">protected</span><span class=\"mtk1\"> </span><span class=\"mtk12\">authenticateRequest</span><span class=\"mtk1\">: </span><span class=\"mtk10\">AuthenticateFn</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        ) { }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">handle</span><span class=\"mtk1\">(</span><span class=\"mtk12\">context</span><span class=\"mtk1\">: </span><span class=\"mtk10\">RequestContext</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">try</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">request</span><span class=\"mtk1\">, </span><span class=\"mtk12\">response</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">context</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">route</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">findRoute</span><span class=\"mtk1\">(</span><span class=\"mtk12\">request</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk3\">//call authentication action</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">authenticateRequest</span><span class=\"mtk1\">(</span><span class=\"mtk12\">request</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk3\">// Authentication successful, proceed to invoke controller</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">args</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">parseParams</span><span class=\"mtk1\">(</span><span class=\"mtk12\">request</span><span class=\"mtk1\">, </span><span class=\"mtk12\">route</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">invoke</span><span class=\"mtk1\">(</span><span class=\"mtk12\">route</span><span class=\"mtk1\">, </span><span class=\"mtk12\">args</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">send</span><span class=\"mtk1\">(</span><span class=\"mtk12\">response</span><span class=\"mtk1\">, </span><span class=\"mtk12\">result</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            } </span><span class=\"mtk15\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">code</span><span class=\"mtk1\"> === </span><span class=\"mtk12\">AUTHENTICATION_STRATEGY_NOT_FOUND</span><span class=\"mtk1\"> ||</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">code</span><span class=\"mtk1\"> === </span><span class=\"mtk12\">USER_PROFILE_NOT_FOUND</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                ) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk10\">Object</span><span class=\"mtk1\">.</span><span class=\"mtk11\">assign</span><span class=\"mtk1\">(</span><span class=\"mtk12\">error</span><span class=\"mtk1\">, { </span><span class=\"mtk12\">statusCode:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">401</span><span class=\"mtk3\">/* Unauthorized */</span><span class=\"mtk1\"> });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">reject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">context</span><span class=\"mtk1\">, </span><span class=\"mtk12\">error</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">return</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span></code></pre>\n<h2 id=\"protect-news-endpoints\" style=\"position:relative;\"><a href=\"#protect-news-endpoints\" aria-label=\"protect news endpoints permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Protect News Endpoints</h2>\n<p>So far, you've implemented user authentication for your API. Now, protect your News endpoints so that only authenticated users can access those routes.</p>\n<p>Open the <code>src/controllers/news.controller.ts</code> file, and import <code>authenticate</code> from jwt authentication.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"20\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">authenticate</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;@loopback/authentication&quot;</span></span></code></pre>\n<p>Then on each of the endpoints in your news controller, add <code>@authenticate('jwt')</code> before the <code>NewsController</code> class, which will protect all the routes in <code>NewsController</code>.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"21\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">//...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    @</span><span class=\"mtk11\">authenticate</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;jwt&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">//...</span></span></code></pre>\n<p>Perhaps, you may not want to protect all the routes, simply add the <code>@authenticate('jwt')</code> method before the route you wish to protect. You can protect the POST route as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"22\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    @</span><span class=\"mtk11\">authenticate</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;jwt&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    @</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/news-models&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      @</span><span class=\"mtk11\">response</span><span class=\"mtk1\">(</span><span class=\"mtk7\">200</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">description:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;NewsModel model instance&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">content:</span><span class=\"mtk1\"> { </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">schema:</span><span class=\"mtk1\"> </span><span class=\"mtk11\">getModelSchemaRef</span><span class=\"mtk1\">(</span><span class=\"mtk12\">NewsModel</span><span class=\"mtk1\">) } },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">create</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        @</span><span class=\"mtk11\">requestBody</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">content:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">schema:</span><span class=\"mtk1\"> </span><span class=\"mtk11\">getModelSchemaRef</span><span class=\"mtk1\">(</span><span class=\"mtk12\">NewsModel</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">title:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;NewNewsModel&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">exclude:</span><span class=\"mtk1\"> [</span><span class=\"mtk8\">&#39;id&#39;</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              }),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">newsModel</span><span class=\"mtk1\">: </span><span class=\"mtk12\">Omit</span><span class=\"mtk1\">&lt;</span><span class=\"mtk12\">NewsModel</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;id&#39;</span><span class=\"mtk1\">&gt;,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      ): </span><span class=\"mtk10\">Promise</span><span class=\"mtk1\">&lt;</span><span class=\"mtk12\">NewsModel</span><span class=\"mtk1\">&gt; {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        return this.newsModelRepository.create(newsModel);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      }</span></span></code></pre>\n<h2 id=\"test-your-application\" style=\"position:relative;\"><a href=\"#test-your-application\" aria-label=\"test your application permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test Your Application</h2>\n<p>You've implemented user authentication in your REST API and secured the routes against unauthorized users. Let's put your application to the test. Press <code>CTRL-C</code> to exit the server and restart it with the following command:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"23\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    npm start</span></span></code></pre>\n<p>If you open the explorer page, you should see the <code>UserController</code> endpoints.</p>\n<p><img src=\"/1f93015b74e330c7dd57e99d9145a9d8/IaV4R43g.webp\" alt=\"User Controller Endpoints\"></p>\n<p>If you try to execute any query on <code>NewsController</code>, you get a 404 (Unauthorized) error. So, sign up by clicking the <code>/signup</code> endpoint — and log in from the <code>/users/login</code> endpoint. On successful login, copy the token, scroll to the top, click on the <code>Authorize</code> button, and paste the token.</p>\n<p><img src=\"/3308ca6960b64dab62adf3646b42032a/atU6nqmA.webp\" alt=\"Authorizing Users\"></p>\n<p>Now you can execute queries on the <code>NewController</code> endpoints.</p>\n<h2 id=\"user-authentication-with-loginradius\" style=\"position:relative;\"><a href=\"#user-authentication-with-loginradius\" aria-label=\"user authentication with loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>User Authentication with Loginradius</h2>\n<p>LoginRadius is a customer identity and access management (CIAM) platform for developers.</p>\n<p>What does this mean for developers like you?</p>\n<p>LoginRadius simplifies the process of user authentication, authorization, and management across web and mobile apps and APIs. It helps developers quickly implement this functionality so that developers, like you, can focus more on building core features that are essential to their apps.</p>\n<p>Loginradius includes a plethora of enticing CIAM features such as passwordless authentication and social SSO (Twitter, Facebook, etc., based single sign-on).</p>\n<p>Implementing user authentication with LoginRadius is a simple procedure. First, sign up for a Developer Pro trial or simply <a href=\"https://accounts.loginradius.com/auth.aspx?action=register\">sign up for a forever free account here</a>.</p>\n<p>And you can explore what LoginRadius can do by using it for a Node.js application. You can learn more by going through <a href=\"https://www.loginradius.com/developers/\">LoginRadius Node.js developer documentation</a></p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>This tutorial taught you how to create user authentication in a LoopBack REST API by creating a small news database application.</p>\n<p>You can use the steps outlined in this tutorial to create any type of LoopBack REST API that requires user authentication and authorization.</p>\n<p>I hope you enjoyed this tutorial! Feel free to contact me on <a href=\"https://twitter.com/EkekentaZion\">Twitter</a>.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n</style>","frontmatter":{"date":"February 04, 2022","updated_date":null,"title":"How to Secure Your LoopBack REST API with JWT Authentication","tags":["Authentication","LoopBack","JWT","Node.js"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/4a5b6d544acaf9e9a42893f7df9dd057/58556/secure-loopback-rest-api-with-jwt.webp","srcSet":"/static/4a5b6d544acaf9e9a42893f7df9dd057/61e93/secure-loopback-rest-api-with-jwt.webp 200w,\n/static/4a5b6d544acaf9e9a42893f7df9dd057/1f5c5/secure-loopback-rest-api-with-jwt.webp 400w,\n/static/4a5b6d544acaf9e9a42893f7df9dd057/58556/secure-loopback-rest-api-with-jwt.webp 800w,\n/static/4a5b6d544acaf9e9a42893f7df9dd057/99238/secure-loopback-rest-api-with-jwt.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Ekekenta Odionyenfe Clinton","github":"icode247","avatar":null}}}},{"node":{"fields":{"slug":"/engineering/guest-post/nodejs-authentication-guide/"},"html":"<h2 id=\"introduction\" style=\"position:relative;\"><a href=\"#introduction\" aria-label=\"introduction permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Introduction</h2>\n<p>Creating a user registration form employs the management of the registered user. This is where user role authentication comes into play. Role authentication ensures that non-admin users cannot make changes or access exclusive information. It grants administrative privileges to admin users and basic privileges to basic users.</p>\n<p>You can build your own authentication functionality with web tokens like JSON Web Token (JWT) or use a trusted third-party customer identity and access management (CIAM) software like LoginRadius.</p>\n<h2 id=\"goal\" style=\"position:relative;\"><a href=\"#goal\" aria-label=\"goal permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Goal</h2>\n<p>This tutorial helps you:</p>\n<ul>\n<li>understand the differences between the Admin role and the Basic user role;</li>\n<li>use JWT to authenticate users; and</li>\n<li>learn role-based authentication using JWT in a simple Node.js app.</li>\n</ul>\n<h2 id=\"prerequisites\" style=\"position:relative;\"><a href=\"#prerequisites\" aria-label=\"prerequisites permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Prerequisites</h2>\n<p>You have installed the following:</p>\n<ul>\n<li><a href=\"https://nodejs.org/en/download/\">Node</a></li>\n<li><a href=\"https://www.mongodb.com/try/download/community\">MongoDB</a></li>\n<li>a <a href=\"https://code.visualstudio.com/download\">Text Editor</a></li>\n</ul>\n<p>You already understand JavaScript <a href=\"https://www.w3schools.com/js/js_es6.asp\">E56 Syntax</a>.</p>\n<p>Now that everything is in place, let's set up your database.</p>\n<h2 id=\"set-up-a-mongo-database\" style=\"position:relative;\"><a href=\"#set-up-a-mongo-database\" aria-label=\"set up a mongo database permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Set Up a Mongo Database</h2>\n<p>You'll store all your user data — which includes username, password, and role — in MongoDB.</p>\n<p>Install a node package called Mongoose that will connect to MongoDB. Then create a user <code>schema</code> for your application.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">npm</span><span class=\"mtk1\"> </span><span class=\"mtk12\">init</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">npm</span><span class=\"mtk1\"> </span><span class=\"mtk12\">install</span><span class=\"mtk1\"> </span><span class=\"mtk12\">mongoose</span></span></code></pre>\n<p><code>npm init</code> sets up your new project and creates a <code>package.json</code> file with the credentials.</p>\n<p>After installing mongoose, create a new file <code>db.js</code> in the project's directory and require <code>mongoose</code>.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Mongoose</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;mongoose&quot;</span><span class=\"mtk1\">)</span></span></code></pre>\n<p>With the help of mongoose, you can connect your application to MongoDB:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">// db.js</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Mongoose</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;mongoose&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">localDB</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">`mongodb://localhost:27017/role_auth`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">connectDB</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Mongoose</span><span class=\"mtk1\">.</span><span class=\"mtk11\">connect</span><span class=\"mtk1\">(</span><span class=\"mtk12\">localDB</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">useNewUrlParser:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">useUnifiedTopology:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;MongoDB Connected&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">module</span><span class=\"mtk1\">.</span><span class=\"mtk10\">exports</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">connectDB</span></span></code></pre>\n<p>The code snippet here connects to <code>mongodb://localhost:27017</code> and then specifies the name of the database <code>/role_auth</code>.</p>\n<p>The function <code>connectDB</code> awaits for the connection, which contains the <code>URI</code> and <code>options</code> as a second parameter. If it connects without errors, it will log out <code>MongoDB Connected</code>. Error issues will be fixed while connecting to the database. After this, it exported the function for use in the server.</p>\n<h2 id=\"set-up-the-server\" style=\"position:relative;\"><a href=\"#set-up-the-server\" aria-label=\"set up the server permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Set Up the Server</h2>\n<p>You need to install some dependencies that you'll use in this tutorial.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">npm</span><span class=\"mtk1\"> </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> </span><span class=\"mtk12\">express</span><span class=\"mtk1\"> </span><span class=\"mtk12\">nodemon</span></span></code></pre>\n<p><a href=\"https://expressjs.com/\">Express.js</a> is a Node.js framework for building web applications quickly and easily.</p>\n<p><a href=\"https://www.npmjs.com/package/nodemon\">Nodemon</a> is a tool that watches the file system and automatically restarts the server when there is a change.</p>\n<p>You require <code>express</code> in your application to listen for a connection on port <code>5000</code>. Create a new file <code>server.js</code> in the root directory and create the listening event:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">express</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;express&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">app</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">express</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">PORT</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">5000</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">listen</span><span class=\"mtk1\">(</span><span class=\"mtk12\">PORT</span><span class=\"mtk1\">, () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">`Server Connected to port </span><span class=\"mtk4\">${</span><span class=\"mtk12\">PORT</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span><span class=\"mtk1\">))</span></span></code></pre>\n<p>The next step is to test your application. Open up your <code>package.json</code> file and add the following to <code>scripts</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"json\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk8\">&quot;scripts&quot;</span><span class=\"mtk1\">: {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">&quot;start&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;node server.js&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">&quot;dev&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;nodemon server.js&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Open your terminal and run <code>npm run dev</code> to start the server.</p>\n<h2 id=\"connect-to-the-database\" style=\"position:relative;\"><a href=\"#connect-to-the-database\" aria-label=\"connect to the database permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Connect to the Database</h2>\n<p>Earlier, you've created a function that connects to MongoDB and exported that function. Now import that function into your <code>server.js</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">connectDB</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;./db&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//Connecting the Database</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">connectDB</span><span class=\"mtk1\">();</span></span></code></pre>\n<p>You also need to create an error handler that catches every <code>unhandledRejection</code> error.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">server</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">listen</span><span class=\"mtk1\">(</span><span class=\"mtk12\">PORT</span><span class=\"mtk1\">, () </span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">`Server Connected to port </span><span class=\"mtk4\">${</span><span class=\"mtk12\">PORT</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// Handling Error</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">process</span><span class=\"mtk1\">.</span><span class=\"mtk11\">on</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;unhandledRejection&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">err</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">`An error occurred: </span><span class=\"mtk4\">${</span><span class=\"mtk12\">err</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">server</span><span class=\"mtk1\">.</span><span class=\"mtk11\">close</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">process</span><span class=\"mtk1\">.</span><span class=\"mtk11\">exit</span><span class=\"mtk1\">(</span><span class=\"mtk7\">1</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span></code></pre>\n<p>The listening event is assigned to a constant <code>server</code>. If an <code>unhandledRejection</code> error occurs, it logs out the error and closes the <code>server</code> with an exit code of 1.</p>\n<h2 id=\"create-user-schema\" style=\"position:relative;\"><a href=\"#create-user-schema\" aria-label=\"create user schema permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create User Schema</h2>\n<p><a href=\"https://en.wikipedia.org/wiki/Database_schema\">Schema</a> is like a blueprint that shows how the database will be constructed.</p>\n<p>You'll structure a user schema that contains username, password, and role.</p>\n<p>Create a new folder <code>model</code> in the project's directory, and create a file called <code>User.js</code>. Now open <code>User.js</code> and create the user schema:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">// user.js</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Mongoose</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;mongoose&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">UserSchema</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Mongoose</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Schema</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">String</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">unique:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">required:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">String</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">minlength:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">6</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">required:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">role:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">String</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">default:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Basic&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">required:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span></code></pre>\n<p>In the schema, the <code>username</code> will be unique, required, and will accept <code>strings</code>.</p>\n<p>You've specified the minimum characters(6) the <code>password</code> field will accept. The <code>role</code> field grants a default value (basic) that you can change if needed.</p>\n<p>Now, you need to create a user model and export it:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">Mongoose</span><span class=\"mtk1\">.</span><span class=\"mtk11\">model</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;user&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">UserSchema</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">module</span><span class=\"mtk1\">.</span><span class=\"mtk10\">exports</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">User</span></span></code></pre>\n<p>You've created the user model by passing the <code>UserSchema</code> as the second argument while the first argument is the name of the model <code>user</code>.</p>\n<h2 id=\"perform-crud-operations\" style=\"position:relative;\"><a href=\"#perform-crud-operations\" aria-label=\"perform crud operations permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Perform CRUD Operations</h2>\n<p>You'll create functions that handle:</p>\n<ul>\n<li>adding users;</li>\n<li>getting all users;</li>\n<li>updating the role of users; and,</li>\n<li>deleting users.</li>\n</ul>\n<h3 id=\"register-function\" style=\"position:relative;\"><a href=\"#register-function\" aria-label=\"register function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Register Function</h3>\n<p>As the name implies, this function will handle the registrations of users.</p>\n<p>Let's create a new folder named <code>Auth</code>. It will contain the Authentication file and the Route set-up file.</p>\n<p>After creating the <code>Auth</code> folder, add two files — <code>Auth.js</code> and <code>Route.js</code>.</p>\n<p>Now open up our <code>Auth.js</code> file and import that <code>User</code> model:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;../model/User&quot;</span><span class=\"mtk1\">)</span></span></code></pre>\n<p>The next step is to create an <code>async</code> <code>express</code> function that will take the user's data and register it in the database.</p>\n<p>You need to use an <a href=\"https://expressjs.com/en/guide/writing-middleware.html\">Express middleware</a> function that will grant access to the user's data from the body. You'll use this function in the <code>server.js</code> file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">app</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">express</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk12\">express</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">())</span></span></code></pre>\n<p>Let's go back to your <code>Auth.js</code> file and create the register function:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"12\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">// auth.js</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">register</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">password</span><span class=\"mtk1\">.</span><span class=\"mtk12\">length</span><span class=\"mtk1\"> &lt; </span><span class=\"mtk7\">6</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Password less than 6 characters&quot;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">try</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\">.</span><span class=\"mtk11\">create</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">username</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">password</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }).</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">user</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">200</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User successfully created&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">user</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User not successful created&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">mesage</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The exported <code>register</code> function will be used to set up the routes. You got the username and password from the <code>req.body</code> and created a <code>tryCatch</code> block that will create the user if successful; else, it returns status code <code>401</code> with the error message.</p>\n<h3 id=\"set-up-register-route\" style=\"position:relative;\"><a href=\"#set-up-register-route\" aria-label=\"set up register route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Set Up Register Route</h3>\n<p>You'll create a route to <code>/register</code> using <code>express.Router</code>. Import the <code>register</code> function into your <code>route.js</code> file, and use it as the route's function:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"13\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">express</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;express&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">express</span><span class=\"mtk1\">.</span><span class=\"mtk11\">Router</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">register</span><span class=\"mtk1\"> } = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;./auth&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/register&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk12\">register</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">module</span><span class=\"mtk1\">.</span><span class=\"mtk10\">exports</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">router</span></span></code></pre>\n<p>The last step is to import your <code>route.js</code> file as middleware in <code>server.js</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"14\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/api/auth&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;./Auth/route&quot;</span><span class=\"mtk1\">))</span></span></code></pre>\n<p>The server will use the <code>router</code> middleware function if there is a request to <code>/api/auth</code>.</p>\n<h3 id=\"test-the-register-route\" style=\"position:relative;\"><a href=\"#test-the-register-route\" aria-label=\"test the register route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test the Register Route</h3>\n<p>You'll use <a href=\"https://www.postman.com/downloads/\">Postman</a> to test all the routes.</p>\n<p>Open up Postman to send a <code>POST</code> request to <code>http://localhost:5000/api/auth/register</code> and pass the username and password to the body:</p>\n<p><img src=\"/1ac77cdb1d6c5ebf46cf5171d74cf4a0/registerRoute.webp\" alt=\"Register Route\"></p>\n<h3 id=\"login-function\" style=\"position:relative;\"><a href=\"#login-function\" aria-label=\"login function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Login Function</h3>\n<p>You've created a function that adds registered users to the database. You have to create another function that will authenticate user credentials and check if the user is registered.</p>\n<p>Open the <code>Auth.js</code> file and create the Login function, as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"15\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">// auth.js</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">login</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk3\">// Check if username and password is provided</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (!</span><span class=\"mtk12\">username</span><span class=\"mtk1\"> || !</span><span class=\"mtk12\">password</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Username or Password not present&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The <code>login</code> function returns status code <code>400</code> if the username and password were not provided. You need to find a user with the provided <code>username</code> and <code>password</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"16\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">login</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">try</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\">.</span><span class=\"mtk11\">findOne</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (!</span><span class=\"mtk12\">user</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Login not successful&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User not found&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">200</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Login successful&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">user</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;An error occurred&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Here, it returns status code <code>401</code> when a user isn't found and <code>200</code> when a user is found. The code snippet wrapped all this in a <code>tryCatch</code> block to detect and output errors, if any.</p>\n<h3 id=\"set-up-login-route\" style=\"position:relative;\"><a href=\"#set-up-login-route\" aria-label=\"set up login route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Set Up Login Route</h3>\n<p>To set up the login route, import the <code>login</code> function into your <code>route.js</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"17\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">express</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;express&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">express</span><span class=\"mtk1\">.</span><span class=\"mtk11\">Router</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">register</span><span class=\"mtk1\">, </span><span class=\"mtk12\">login</span><span class=\"mtk1\"> } = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;./auth&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk12\">login</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">module</span><span class=\"mtk1\">.</span><span class=\"mtk10\">exports</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">router</span><span class=\"mtk1\">;</span></span></code></pre>\n<h3 id=\"test-the-login-route\" style=\"position:relative;\"><a href=\"#test-the-login-route\" aria-label=\"test the login route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test the Login Route</h3>\n<p>Make a <code>POST</code> request at <code>http://localhost:5000/api/auth/login</code> and pass a valid username and password to the body:</p>\n<p><img src=\"/bdcb632806567d22933fc46296bc322c/loginroute.webp\" alt=\"login Route\"></p>\n<h3 id=\"update-function\" style=\"position:relative;\"><a href=\"#update-function\" aria-label=\"update function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Update Function</h3>\n<p>This function will be responsibile for updating the role of a basic user to an admin user. Open the <code>auth.js</code> file and create the <code>update</code> function, as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"18\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">//auth.js</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">update</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">role</span><span class=\"mtk1\">, </span><span class=\"mtk12\">id</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk3\">// Verifying if role and id is presnt</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">id</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">// Verifying if the value of role is admin</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> === </span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\">.</span><span class=\"mtk11\">findById</span><span class=\"mtk1\">(</span><span class=\"mtk12\">id</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Role is not admin&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Role or Id not present&quot;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The first <code>if</code> statement verifies if <code>role</code> and <code>id</code> are present in the request body.</p>\n<p>The second <code>if</code> statement checks if the value of <code>role</code> is admin. You should do this to avoid having over two roles.</p>\n<p>After finding a user with that ID, you'll create a third <code>if</code> block that will check for the role of the user:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"19\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">update</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">role</span><span class=\"mtk1\">, </span><span class=\"mtk12\">id</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk3\">// First - Verifying if role and id is presnt</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">id</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">// Second - Verifying if the value of role is admin</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> === </span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk3\">// Finds the user with the id</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\">.</span><span class=\"mtk11\">findById</span><span class=\"mtk1\">(</span><span class=\"mtk12\">id</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">((</span><span class=\"mtk12\">user</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk3\">// Third - Verifies the user is not an admin</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> !== </span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">role</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk11\">save</span><span class=\"mtk1\">((</span><span class=\"mtk12\">err</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk3\">//Monogodb error checker</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">res</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                  .</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;400&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                  .</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;An error occurred&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">err</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk1\"> });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">process</span><span class=\"mtk1\">.</span><span class=\"mtk11\">exit</span><span class=\"mtk1\">(</span><span class=\"mtk7\">1</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;201&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Update successful&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User is already an Admin&quot;</span><span class=\"mtk1\"> });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">catch</span><span class=\"mtk1\">((</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">res</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            .</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            .</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;An error occurred&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk1\"> });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        });</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       ...</span></span></code></pre>\n<p>The third <code>if</code> block prevents assigning an admin role to an admin user, while the last <code>if</code> block checks if an error occurred when saving the role in the database.</p>\n<blockquote>\n<p>The numerous <code>if</code> statements might be a little bit tricky but understandable. Please read the comments in the above code block for better understanding.</p>\n</blockquote>\n<h3 id=\"set-up-update-route\" style=\"position:relative;\"><a href=\"#set-up-update-route\" aria-label=\"set up update route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Set Up Update Route</h3>\n<p>Import the <code>update</code> function in your <code>route.js</code>, as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"20\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">register</span><span class=\"mtk1\">, </span><span class=\"mtk12\">login</span><span class=\"mtk1\">, </span><span class=\"mtk12\">update</span><span class=\"mtk1\"> } = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;./auth&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/update&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">put</span><span class=\"mtk1\">(</span><span class=\"mtk12\">update</span><span class=\"mtk1\">);</span></span></code></pre>\n<h3 id=\"testing-the-update-route\" style=\"position:relative;\"><a href=\"#testing-the-update-route\" aria-label=\"testing the update route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Testing the Update Route</h3>\n<p>Send a <code>put</code> request to <code>http://localhost:5000/api/auth/update</code>:</p>\n<p><img src=\"/0a64d4ef9c1c8955d9aed82aaf869472/updateroute.webp\" alt=\"update Route\"></p>\n<h3 id=\"delete-function\" style=\"position:relative;\"><a href=\"#delete-function\" aria-label=\"delete function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Delete Function</h3>\n<p>The <code>deleteUser</code> function will remove a specific user from the database. Let's create this function in our <code>auth.js</code> file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"21\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">deleteUser</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">id</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\">.</span><span class=\"mtk11\">findById</span><span class=\"mtk1\">(</span><span class=\"mtk12\">id</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">user</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk11\">remove</span><span class=\"mtk1\">())</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">user</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">201</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User successfully deleted&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">catch</span><span class=\"mtk1\">(</span><span class=\"mtk12\">error</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">res</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;An error occurred&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>You remove the user based on the <code>id</code> you get from <code>req.body</code>.</p>\n<h3 id=\"set-up-the-deleteuser-route\" style=\"position:relative;\"><a href=\"#set-up-the-deleteuser-route\" aria-label=\"set up the deleteuser route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Set up the <code>deleteUser</code> Route</h3>\n<p>Open your <code>route.js</code> file to create a <code>delete</code> request to <code>/deleteUser</code>, using the <code>deleteUser</code> as its function:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"22\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">register</span><span class=\"mtk1\">, </span><span class=\"mtk12\">login</span><span class=\"mtk1\">, </span><span class=\"mtk12\">update</span><span class=\"mtk1\">, </span><span class=\"mtk12\">deleteUser</span><span class=\"mtk1\"> } = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;./auth&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/deleteUser&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">delete</span><span class=\"mtk1\">(</span><span class=\"mtk12\">deleteUser</span><span class=\"mtk1\">);</span></span></code></pre>\n<h3 id=\"test-the-deleteuser-route\" style=\"position:relative;\"><a href=\"#test-the-deleteuser-route\" aria-label=\"test the deleteuser route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test the <code>deleteUser</code> Route</h3>\n<p>Send a <code>delete</code> request to <code>http://localhost:5000/api/auth/deleteUser</code> by passing a valid <code>id</code> to the body:</p>\n<p><img src=\"/5f7478fb8c45b5a5def8d442ab1d259c/deleteroute.webp\" alt=\"Delete Route\"></p>\n<h2 id=\"hash-user-passwords\" style=\"position:relative;\"><a href=\"#hash-user-passwords\" aria-label=\"hash user passwords permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Hash User Passwords</h2>\n<p>Saving user passwords in the database in plain text format is reckless. It is preferable to hash your password before storing it.</p>\n<p>For instance, it will be tough to decipher the passwords in your database if they are leaked. Hashing passwords is a cautious and reliable practice.</p>\n<p>Let's use <code>bcryptjs</code> to hash your user passwords.</p>\n<p>Lets install <code>bcryptjs</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"23\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">npm</span><span class=\"mtk1\"> </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bcryptjs</span></span></code></pre>\n<p>After installing <code>bcryptjs</code>, import it into your <code>auth.js</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"24\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;bcryptjs&quot;</span><span class=\"mtk1\">)</span></span></code></pre>\n<h3 id=\"refactor-register-function\" style=\"position:relative;\"><a href=\"#refactor-register-function\" aria-label=\"refactor register function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Refactor Register Function</h3>\n<p>Instead of sending a plain text format to your database, lets hash the password using <code>bcrypt</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"25\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">register</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ...</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">hash</span><span class=\"mtk1\">(</span><span class=\"mtk12\">password</span><span class=\"mtk1\">, </span><span class=\"mtk7\">10</span><span class=\"mtk1\">).</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">hash</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\">.</span><span class=\"mtk11\">create</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">username</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">hash</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">((</span><span class=\"mtk12\">user</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">200</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User successfully created&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">           </span><span class=\"mtk12\">user</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      .</span><span class=\"mtk11\">catch</span><span class=\"mtk1\">((</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User not successful created&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span></code></pre>\n<p><code>bcrypt</code> takes in your password as the first argument and the number of times it will hash the password as the second argument. Passing a large number will take <code>bcrypt</code> a long time to hash the password, so give a moderate number like 10.</p>\n<p><code>bcrypt</code> will return a promise with the hashed password; then, send that hashed password to the database.</p>\n<h3 id=\"test-the-register-function\" style=\"position:relative;\"><a href=\"#test-the-register-function\" aria-label=\"test the register function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test the Register Function</h3>\n<p>Send a <code>POST</code> request to <code>http://localhost:5000/api/auth/register</code> and pass the username and password to the body:</p>\n<p><img src=\"/1ac77cdb1d6c5ebf46cf5171d74cf4a0/Hashedregisterroute.webp\" alt=\"Register Route\"></p>\n<h3 id=\"refactor-the-login-function\" style=\"position:relative;\"><a href=\"#refactor-the-login-function\" aria-label=\"refactor the login function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Refactor the Login Function</h3>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"26\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">login</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk3\">// Check if username and password is provided</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (!</span><span class=\"mtk12\">username</span><span class=\"mtk1\"> || !</span><span class=\"mtk12\">password</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Username or Password not present&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">try</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\">.</span><span class=\"mtk11\">findOne</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">username</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (!</span><span class=\"mtk12\">user</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Login not successful&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User not found&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk3\">// comparing given password with hashed password</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">compare</span><span class=\"mtk1\">(</span><span class=\"mtk12\">password</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">password</span><span class=\"mtk1\">).</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk4\">function</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">result</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">result</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          ? </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">200</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Login successful&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">user</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          : </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Login not succesful&quot;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;An error occurred&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p><code>bcrypt.compare</code> checks if the given password and the hashed password in the database are the same.</p>\n<h3 id=\"test-the-login-function\" style=\"position:relative;\"><a href=\"#test-the-login-function\" aria-label=\"test the login function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test the Login Function</h3>\n<p>Send a <code>POST</code> request to <code>http://localhost:5000/api/auth/login</code> and pass a valid username and password to the body:</p>\n<p><img src=\"/632b08fece37d70e9641393af6d9dbcd/hashedloginroute.webp\" alt=\"Hashed Login Route\"></p>\n<h2 id=\"authenticate-users-with-json-web-token-jwt\" style=\"position:relative;\"><a href=\"#authenticate-users-with-json-web-token-jwt\" aria-label=\"authenticate users with json web token jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Authenticate Users with JSON Web Token (JWT)</h2>\n<p>JSON Web Token helps shield a route from an unauthenticated user. Using JWT in your application will prevent unauthenticated users from accessing your users' home page and prevent unauthorized users from accessing your admin page.</p>\n<p>JWT creates a token, sends it to the client, and then the client uses the token for making requests. It also helps verify that you're a valid user making those requests.</p>\n<p>You've to install JWT before using it in your application:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"27\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">npm</span><span class=\"mtk1\"> </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jsonwebtoken</span></span></code></pre>\n<h3 id=\"refactor-the-register-function\" style=\"position:relative;\"><a href=\"#refactor-the-register-function\" aria-label=\"refactor the register function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Refactor the Register Function</h3>\n<p>When a user registers, you'll send a token to the client using JWT as a cookie. To create this token, you need to set a secret string. You'll use the node's in-built package called <code>crypto</code> to create random strings:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"28\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">node</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;crypto&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">randomBytes</span><span class=\"mtk1\">(</span><span class=\"mtk7\">35</span><span class=\"mtk1\">).</span><span class=\"mtk11\">toString</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;hex&quot;</span><span class=\"mtk1\">)</span></span></code></pre>\n<p>Output:</p>\n<p><img src=\"/ffc516c1cf1c578ae020aab9ea7bef3d/crypto.webp\" alt=\"Crypto\"></p>\n<p>Storing this secret string in an environment variable is a safe practice. If this secret string is leaked, unauthenticated users can create fake tokens to access the route.</p>\n<p>Store your secret string in a variable:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"29\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jwtSecret</span><span class=\"mtk1\"> =</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk8\">&quot;4715aed3c946f7b0a38e6b534a9583628d84e96d10fbc04700770d572af3dce43625dd&quot;</span></span></code></pre>\n<p>Once you've created your <code>jwtSecret</code>, import <code>jsonwebtoken</code> as the token in the <code>register</code> function:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"30\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;jsonwebtoken&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jwtSecret</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&#39;4715aed3c946f7b0a38e6b534a9583628d84e96d10fbc04700770d572af3dce43625dd&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">register</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ...</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">hash</span><span class=\"mtk1\">(</span><span class=\"mtk12\">password</span><span class=\"mtk1\">, </span><span class=\"mtk7\">10</span><span class=\"mtk1\">).</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">hash</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\">.</span><span class=\"mtk11\">create</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">username</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">hash</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">((</span><span class=\"mtk12\">user</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">maxAge</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">3</span><span class=\"mtk1\"> * </span><span class=\"mtk7\">60</span><span class=\"mtk1\"> * </span><span class=\"mtk7\">60</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">token</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">sign</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          { </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">_id</span><span class=\"mtk1\">, </span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">role:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">jwtSecret</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">expiresIn:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">maxAge</span><span class=\"mtk1\">, </span><span class=\"mtk3\">// 3hrs in sec</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">cookie</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;jwt&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">token</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">httpOnly:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">maxAge:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">maxAge</span><span class=\"mtk1\"> * </span><span class=\"mtk7\">1000</span><span class=\"mtk1\">, </span><span class=\"mtk3\">// 3hrs in ms</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">201</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User successfully created&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">user:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">_id</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      .</span><span class=\"mtk11\">catch</span><span class=\"mtk1\">((</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User not successful created&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span></code></pre>\n<p>The code snippet created the token using JWT's <code>sign</code> function. This function takes in three parameters:</p>\n<ul>\n<li>the payload is the first parament that you'll pass to the function. This payload holds data concerning the user, and this data should not contain sensitive information like passwords;</li>\n<li>you passed your <code>jwtSecret</code> as the second parameter; and,</li>\n<li>how long the token will last as the third parameter.</li>\n</ul>\n<p>After passing all these arguments, JWT will generate a token. After the token is generated, send it as a cookie to the client.</p>\n<h3 id=\"refactor-the-login-function-1\" style=\"position:relative;\"><a href=\"#refactor-the-login-function-1\" aria-label=\"refactor the login function 1 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Refactor the Login Function</h3>\n<p>Also, generate a token for logged in users:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"31\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">login</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ...</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">compare</span><span class=\"mtk1\">(</span><span class=\"mtk12\">password</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">password</span><span class=\"mtk1\">).</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk4\">function</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">result</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">result</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">maxAge</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">3</span><span class=\"mtk1\"> * </span><span class=\"mtk7\">60</span><span class=\"mtk1\"> * </span><span class=\"mtk7\">60</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">token</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">sign</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            { </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">_id</span><span class=\"mtk1\">, </span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">role:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">jwtSecret</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">expiresIn:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">maxAge</span><span class=\"mtk1\">, </span><span class=\"mtk3\">// 3hrs in sec</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">cookie</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;jwt&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">token</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">httpOnly:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">maxAge:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">maxAge</span><span class=\"mtk1\"> * </span><span class=\"mtk7\">1000</span><span class=\"mtk1\">, </span><span class=\"mtk3\">// 3hrs in ms</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">201</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;User successfully Logged in&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">user:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">_id</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Login not succesful&quot;</span><span class=\"mtk1\"> });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">error</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;An error occurred&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">error</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span></code></pre>\n<h3 id=\"protect-the-routes\" style=\"position:relative;\"><a href=\"#protect-the-routes\" aria-label=\"protect the routes permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Protect the Routes</h3>\n<p>To prevent unauthenticated users from accessing the private route, take the token from the cookie, verify the token, and redirect users based on role.</p>\n<p>You'll get the token from the client using a node package called <code>cookie-parser</code>. Let's install the package before using it:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"32\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">npm</span><span class=\"mtk1\"> </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> </span><span class=\"mtk12\">cookie</span><span class=\"mtk1\">-</span><span class=\"mtk12\">parser</span></span></code></pre>\n<p>After installing it, import it into your <code>server.js</code> file and use it as a <em>middleware</em>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"33\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">cookieParser</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;cookie-parser&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk11\">cookieParser</span><span class=\"mtk1\">());</span></span></code></pre>\n<p>You'll create your middleware that verifies the token and grants access to your private route.</p>\n<p>Let's create a new folder in the project's folder named <code>middleware</code> and create a file called <code>auth.js</code>.</p>\n<h3 id=\"admin-authentication\" style=\"position:relative;\"><a href=\"#admin-authentication\" aria-label=\"admin authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Admin Authentication</h3>\n<p>Open the <code>auth.js</code> file and create the middleware:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"34\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;jsonwebtoken&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jwtSecret</span><span class=\"mtk1\"> =</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk8\">&quot;4715aed3c946f7b0a38e6b534a9583628d84e96d10fbc04700770d572af3dce43625dd&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">adminAuth</span><span class=\"mtk1\"> = (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">token</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">cookies</span><span class=\"mtk1\">.</span><span class=\"mtk12\">jwt</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">token</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">verify</span><span class=\"mtk1\">(</span><span class=\"mtk12\">token</span><span class=\"mtk1\">, </span><span class=\"mtk12\">jwtSecret</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">, </span><span class=\"mtk12\">decodedToken</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Not authorized&quot;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">decodedToken</span><span class=\"mtk1\">.</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> !== </span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Not authorized&quot;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk11\">next</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      .</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      .</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Not authorized, token not available&quot;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The code snippet requests a token from the client, checks if a token is available, and verifies that token.</p>\n<p>JWT verifies your token with your <code>jwtSecret</code> and returns a callback function. This function returns status code <code>401</code> if the token fails the authentication test.</p>\n<p>When you've created the token, you passed a payload that contained the user's credentials. You'll get the role from the credentials and check if the user's role is admin. If the user is not an admin, you return status code <code>401</code>, but you'll call the <code>next</code> function if the user is an admin.</p>\n<h3 id=\"basic-user-authentication\" style=\"position:relative;\"><a href=\"#basic-user-authentication\" aria-label=\"basic user authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Basic User Authentication</h3>\n<p>You'll also authenticate basic users before granting them access to the users route. Let's create another middleware in your <code>auth.js</code> file that will authenticate basic users:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"35\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">userAuth</span><span class=\"mtk1\"> = (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">token</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">cookies</span><span class=\"mtk1\">.</span><span class=\"mtk12\">jwt</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">token</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">verify</span><span class=\"mtk1\">(</span><span class=\"mtk12\">token</span><span class=\"mtk1\">, </span><span class=\"mtk12\">jwtSecret</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">, </span><span class=\"mtk12\">decodedToken</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Not authorized&quot;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">decodedToken</span><span class=\"mtk1\">.</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> !== </span><span class=\"mtk8\">&quot;Basic&quot;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Not authorized&quot;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk11\">next</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      .</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      .</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Not authorized, token not available&quot;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<h3 id=\"protect-the-routes-1\" style=\"position:relative;\"><a href=\"#protect-the-routes-1\" aria-label=\"protect the routes 1 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Protect the Routes</h3>\n<p>You'll have two routes: one for the user and the other for the admin. Let's import this middleware into your <code>server.js</code> file and protect your routes:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"36\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">adminAuth</span><span class=\"mtk1\">, </span><span class=\"mtk12\">userAuth</span><span class=\"mtk1\"> } = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;./middleware/auth.js&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/admin&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">adminAuth</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">send</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Admin Route&quot;</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/basic&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">userAuth</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">send</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;User Route&quot;</span><span class=\"mtk1\">));</span></span></code></pre>\n<p>Updating user roles and deleting users should be done by an Admin, so you need to import this <code>auth.js</code> middleware into your <code>route.js</code> file to protect the <code>update</code> and <code>delete</code> routes.</p>\n<p><code>route.js</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"37\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">adminAuth</span><span class=\"mtk1\"> } = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;../middleware/auth&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/update&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">put</span><span class=\"mtk1\">(</span><span class=\"mtk12\">adminAuth</span><span class=\"mtk1\">, </span><span class=\"mtk12\">update</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/deleteUser&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">delete</span><span class=\"mtk1\">(</span><span class=\"mtk12\">adminAuth</span><span class=\"mtk1\">, </span><span class=\"mtk12\">deleteUser</span><span class=\"mtk1\">)</span></span></code></pre>\n<h2 id=\"populate-the-database-with-admin-user\" style=\"position:relative;\"><a href=\"#populate-the-database-with-admin-user\" aria-label=\"populate the database with admin user permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Populate the Database with Admin User</h2>\n<p>You need to create an admin user in your database. Open up your terminal, and let's run some <a href=\"https://docs.mongodb.com/manual/reference/method/\">MongoDB methods</a>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"38\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">mongo</span></code></pre>\n<p>After mongo is started, you need to use the <code>role_auth</code> database:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"39\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">use role_auth</span></code></pre>\n<p>Before adding your admin user to the database, you need to hash the password using <code>bcrypt</code> in the <code>node</code> terminal. Open node terminal in your project's directory:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"40\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;bcryptjs&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">hash</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk7\">10</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">password</span></span></code></pre>\n<p>After you've created the constant <code>password</code>, you need to enter <code>the</code> <code>password</code> in the node terminal to get your hashed password.</p>\n<p><img src=\"/d3c1b2d70849b827aac61c69995a2f8f/nodebycrypt.webp\" alt=\"Node bcrypt\"></p>\n<p>You'll use the hashed password to create your admin:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"41\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">db</span><span class=\"mtk1\">.</span><span class=\"mtk12\">users</span><span class=\"mtk1\">.</span><span class=\"mtk11\">insert</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;$2a$10$mZwU9AbYSyX7E1A6fu/ZO.BDhmCOIK7k6jXvKcuJm93PyYuH2eZ3K&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">role:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span></code></pre>\n<p>To check if it was successfully created, run <code>db.users.find().pretty()</code> — this will output all users in the database.</p>\n<h2 id=\"create-the-login-form-using-ejs\" style=\"position:relative;\"><a href=\"#create-the-login-form-using-ejs\" aria-label=\"create the login form using ejs permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create the Login Form Using EJS</h2>\n<p>You'll use Embedded JavaScript (EJS) to create a front-end for your application.</p>\n<p>Install the <code>ejs</code> package:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"42\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">npm</span><span class=\"mtk1\"> </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> </span><span class=\"mtk12\">ejs</span></span></code></pre>\n<p>After you've installed <code>ejs</code>, you need to set <code>ejs</code> as your default <em>view engine</em> in your <code>server.js</code> file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"43\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">set</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;view engine&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;ejs&quot;</span><span class=\"mtk1\">)</span></span></code></pre>\n<h3 id=\"render-embedded-javascript\" style=\"position:relative;\"><a href=\"#render-embedded-javascript\" aria-label=\"render embedded javascript permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Render Embedded JavaScript</h3>\n<p>When making a <code>GET</code> request to specific routes, you'll render an <code>ejs</code> file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"44\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/&quot;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">render</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;home&quot;</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/register&quot;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">render</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;register&quot;</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">render</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;login&quot;</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/admin&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">adminAuth</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">render</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/basic&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">userAuth</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">render</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;user&quot;</span><span class=\"mtk1\">))</span></span></code></pre>\n<h3 id=\"create-ejs-files\" style=\"position:relative;\"><a href=\"#create-ejs-files\" aria-label=\"create ejs files permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create EJS Files</h3>\n<p>By default, your application will look into the <code>views</code> folder when rendering an <code>ejs</code> file. You need to create the <code>views</code> folder in your project's folder and add your <code>ejs</code> files to it</p>\n<h3 id=\"create-a-home-page\" style=\"position:relative;\"><a href=\"#create-a-home-page\" aria-label=\"create a home page permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create a Home Page</h3>\n<p>Your home page will contain the links to <code>/login</code> and <code>/register</code> ejs file. Open up <code>home.ejs</code> and add these links:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"45\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!</span><span class=\"mtk12\">DOCTYPE</span><span class=\"mtk1\"> </span><span class=\"mtk12\">html</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">html</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lang</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;en&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">charset</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;UTF-8&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;viewport&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;width=device-width, initial-scale=1.0&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Home page</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Home Page</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/register&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> Register</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">a</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Login</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">a</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h3 id=\"create-a-registration-form\" style=\"position:relative;\"><a href=\"#create-a-registration-form\" aria-label=\"create a registration form permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create a Registration Form</h3>\n<p>Embedded JavaScript (EJS) supports HTML syntax. You'll create the registration form in <code>register.ejs</code> using HTML syntax:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"46\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!</span><span class=\"mtk12\">DOCTYPE</span><span class=\"mtk1\"> </span><span class=\"mtk12\">html</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">html</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lang</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;en&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">charset</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;UTF-8&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;viewport&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;width=device-width, initial-scale=1.0&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Register Page</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Register Page</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">form</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">style</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;background-color: red;&quot;</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">label</span><span class=\"mtk1\"> </span><span class=\"mtk12\">for</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;username&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Username</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">label</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;text&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;username&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">required</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">label</span><span class=\"mtk1\"> </span><span class=\"mtk12\">for</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Password</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">label</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">required</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;submit&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;register&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">form</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Already registered? Login</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">a</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h3 id=\"add-post-request-functionality\" style=\"position:relative;\"><a href=\"#add-post-request-functionality\" aria-label=\"add post request functionality permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Add POST Request Functionality</h3>\n<p>You need to get the username and password that the user entered and pass it to the body when making the <code>POST</code> request:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"47\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  const form = document.querySelector(&#39;form&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  const username = document.querySelector(&#39;#username&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  const password = document.querySelector(&#39;#password&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  const display = document.querySelector(&#39;.error&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  form.addEventListener(&#39;submit&#39;, async (e) =&gt; </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk12\">e</span><span class=\"mtk1\">.</span><span class=\"mtk11\">preventDefault</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk12\">display</span><span class=\"mtk1\">.</span><span class=\"mtk12\">textContent</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&#39;&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk12\">try</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       const </span><span class=\"mtk12\">res</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/api/auth/register&#39;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span><span class=\"mtk12\">method:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;POST&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">body:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">username</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">password</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\"> }),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> { </span><span class=\"mtk8\">&#39;Content-Type&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk1\"> }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       const </span><span class=\"mtk12\">data</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span><span class=\"mtk11\">if</span><span class=\"mtk1\">(res.status === 400 || res.status === 401){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">display</span><span class=\"mtk1\">.</span><span class=\"mtk12\">textContent</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">`</span><span class=\"mtk4\">${</span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk4\">}</span><span class=\"mtk8\">. </span><span class=\"mtk4\">${</span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk1\"> ? </span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk1\"> : </span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       data.</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> === </span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\"> ? </span><span class=\"mtk12\">location</span><span class=\"mtk1\">.</span><span class=\"mtk11\">assign</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/admin&#39;</span><span class=\"mtk1\">) : </span><span class=\"mtk12\">location</span><span class=\"mtk1\">.</span><span class=\"mtk11\">assign</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/basic&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        } </span><span class=\"mtk11\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          console.log(err.message)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">}</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">&lt;/</span><span class=\"mtk12\">body</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">&lt;/</span><span class=\"mtk12\">html</span><span class=\"mtk1\">&gt;</span></span></code></pre>\n<p>The code snippet uses JavaScript's in-built library called <code>fetch</code> to send a POST request to <code>/api/auth/register</code>.</p>\n<p>After the request has been sent, it stores the response to a constant <code>res</code>.</p>\n<p><code>res.json</code> will return the JSON you've passed as a response in the API.</p>\n<p>When <code>res.json</code> returns the data, you store that data in a constant <code>data</code>.</p>\n<p>If you get an error while making the request, display the error to the user. If an error isn't found, redirect the user based on their role on different routes.</p>\n<h3 id=\"create-a-login-form\" style=\"position:relative;\"><a href=\"#create-a-login-form\" aria-label=\"create a login form permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create a Login Form</h3>\n<p>Creating your login form and adding functionality to it will be similar to that of your registration. Open <code>login.ejs</code> and create this form:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"48\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!</span><span class=\"mtk12\">DOCTYPE</span><span class=\"mtk1\"> </span><span class=\"mtk12\">html</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">html</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lang</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;en&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">charset</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;UTF-8&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;viewport&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;width=device-width, initial-scale=1.0&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Login Page</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Login Page</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">form</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">style</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;background-color: red;&quot;</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">label</span><span class=\"mtk1\"> </span><span class=\"mtk12\">for</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;username&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Username</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">label</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;text&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;username&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">required</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">label</span><span class=\"mtk1\"> </span><span class=\"mtk12\">for</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Password</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">label</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">required</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;submit&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;login&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">form</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/register&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Don&#39;t have an accout? Register</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">a</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h3 id=\"add-post-request-functionality-1\" style=\"position:relative;\"><a href=\"#add-post-request-functionality-1\" aria-label=\"add post request functionality 1 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Add POST Request Functionality</h3>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"49\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const form = document.querySelector(&#39;form&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const username = document.querySelector(&#39;#username&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const password = document.querySelector(&#39;#password&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const display = document.querySelector(&#39;.error&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      form.addEventListener(&#39;submit&#39;, async (e) =&gt; </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">e</span><span class=\"mtk1\">.</span><span class=\"mtk11\">preventDefault</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">display</span><span class=\"mtk1\">.</span><span class=\"mtk12\">textContent</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&#39;&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">try</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          const </span><span class=\"mtk12\">res</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/api/auth/login&#39;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">method:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;POST&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">body:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">username</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">password</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\"> }),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> { </span><span class=\"mtk8\">&#39;Content-Type&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk1\"> }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          const </span><span class=\"mtk12\">data</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk11\">if</span><span class=\"mtk1\"> (res.status === 400 || res.status === 401) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">display</span><span class=\"mtk1\">.</span><span class=\"mtk12\">textContent</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">`</span><span class=\"mtk4\">${</span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk4\">}</span><span class=\"mtk8\">. </span><span class=\"mtk4\">${</span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk1\"> ? </span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk1\"> : </span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          data.</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> === </span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\"> ? </span><span class=\"mtk12\">location</span><span class=\"mtk1\">.</span><span class=\"mtk11\">assign</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/admin&#39;</span><span class=\"mtk1\">) : </span><span class=\"mtk12\">location</span><span class=\"mtk1\">.</span><span class=\"mtk11\">assign</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/basic&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        } </span><span class=\"mtk11\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            console.log(err.message)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">}</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    &lt;/</span><span class=\"mtk12\">body</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    &lt;/</span><span class=\"mtk12\">html</span><span class=\"mtk1\">&gt;</span></span></code></pre>\n<h2 id=\"add-registered-users-to-the-route\" style=\"position:relative;\"><a href=\"#add-registered-users-to-the-route\" aria-label=\"add registered users to the route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Add Registered Users to the Route</h2>\n<p>Once you've redirected users based on role to different routes, display all registered users on that route. You need to send a <code>GET</code> request to <code>/getUsers</code>.</p>\n<p>Open <code>auth.js</code> file in <code>Auth</code> folder:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"50\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getUsers</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">User</span><span class=\"mtk1\">.</span><span class=\"mtk11\">find</span><span class=\"mtk1\">({})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">users</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">userFunction</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">users</span><span class=\"mtk1\">.</span><span class=\"mtk11\">map</span><span class=\"mtk1\">(</span><span class=\"mtk12\">user</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">container</span><span class=\"mtk1\"> = {}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">container</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">container</span><span class=\"mtk1\">.</span><span class=\"mtk12\">role</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">role</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">container</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">200</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">user:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">userFunction</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">catch</span><span class=\"mtk1\">(</span><span class=\"mtk12\">err</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Not successful&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">err</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The <code>User.find</code> method returns an array of users. After mapping through this array, it stores the username and role in the constant <code>container</code> and returns the <code>container</code>.</p>\n<h3 id=\"display-registered-user-in-user-route\" style=\"position:relative;\"><a href=\"#display-registered-user-in-user-route\" aria-label=\"display registered user in user route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Display Registered User in <code>user</code> Route</h3>\n<p>You've rendered <code>user.ejs</code> when accessing the <code>/user</code> route. Now, you'll display all registered users to that route.</p>\n<p><code>user.ejs</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"51\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!</span><span class=\"mtk12\">DOCTYPE</span><span class=\"mtk1\"> </span><span class=\"mtk12\">html</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">html</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lang</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;en&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">charset</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;UTF-8&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">http-equiv</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;X-UA-Compatible&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;IE=edge&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;viewport&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;width=device-width, initial-scale=1.0&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">User page</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Users</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">ul</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">ul</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const ul = document.querySelector(&quot;ul&quot;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const getUsers = async () =&gt; </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/api/auth/getUsers&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">data</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk11\">map</span><span class=\"mtk1\">(</span><span class=\"mtk12\">mappedUser</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">mappedUser</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</span><span class=\"mtk1\"> !== </span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">li</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">`&lt;li&gt; &lt;b&gt;Username&lt;/b&gt; =&gt; </span><span class=\"mtk4\">${</span><span class=\"mtk12\">mappedUser</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</span><span class=\"mtk4\">}</span><span class=\"mtk8\"> &lt;br&gt; &lt;b&gt;Role&lt;/b&gt; =&gt; </span><span class=\"mtk4\">${</span><span class=\"mtk12\">mappedUser</span><span class=\"mtk1\">.</span><span class=\"mtk12\">role</span><span class=\"mtk4\">}</span><span class=\"mtk8\"> &lt;/li&gt;`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">ul</span><span class=\"mtk1\">.</span><span class=\"mtk12\">innerHTML</span><span class=\"mtk1\"> += </span><span class=\"mtk12\">li</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">null</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      getUsers()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h3 id=\"add-update-and-delete-function-to-the-admin-route\" style=\"position:relative;\"><a href=\"#add-update-and-delete-function-to-the-admin-route\" aria-label=\"add update and delete function to the admin route permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Add Update and Delete Function to the Admin Route</h3>\n<p>You'll also display registered users to the admin route but add <code>update</code> and <code>delete</code> functionality to the route:</p>\n<p><code>admin.ejs</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"52\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!</span><span class=\"mtk12\">DOCTYPE</span><span class=\"mtk1\"> </span><span class=\"mtk12\">html</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">html</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lang</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;en&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">charset</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;UTF-8&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">http-equiv</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;X-UA-Compatible&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;IE=edge&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;viewport&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;width=device-width, initial-scale=1.0&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Admin page</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;display&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">style</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;background-color: red;&quot;</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Users</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">ul</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">ul</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const ul = document.querySelector(&quot;ul&quot;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const display = document.querySelector(&quot;.display&quot;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      const getUsers = async () =&gt; </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/api/auth/getUsers&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">data</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk11\">map</span><span class=\"mtk1\">(</span><span class=\"mtk12\">mappedUser</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">mappedUser</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</span><span class=\"mtk1\"> !== </span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">li</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">`&lt;li&gt; &lt;b&gt;Username&lt;/b&gt; =&gt; </span><span class=\"mtk4\">${</span><span class=\"mtk12\">mappedUser</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</span><span class=\"mtk4\">}</span><span class=\"mtk8\"> &lt;br&gt; &lt;b&gt;Role&lt;/b&gt; =&gt; </span><span class=\"mtk4\">${</span><span class=\"mtk12\">mappedUser</span><span class=\"mtk1\">.</span><span class=\"mtk12\">role</span><span class=\"mtk4\">}</span><span class=\"mtk8\"> &lt;/li&gt; &lt;button class=&quot;edit&quot;&gt;Edit Role&lt;/button&gt; &lt;button class=&quot;delete&quot;&gt;Delete User&lt;/button&gt;`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">ul</span><span class=\"mtk1\">.</span><span class=\"mtk12\">innerHTML</span><span class=\"mtk1\"> += </span><span class=\"mtk12\">li</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">null</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">editRole</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">querySelectorAll</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;.edit&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">deleteUser</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">querySelector</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;.delete&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      getUsers()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h3 id=\"edit-a-users-role\" style=\"position:relative;\"><a href=\"#edit-a-users-role\" aria-label=\"edit a users role permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Edit a User's Role</h3>\n<p>You'll create an event listener that will listen for a click on the <code>Edit Role</code> button. When the button is clicked, you'll send a <code>PUT</code> request to <code>/api/auth/update</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"53\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ...</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    const editRole = document.querySelectorAll(&#39;.edit&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    const deleteUser = document.querySelector(&#39;.delete&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  editRole.forEach((button, i) =&gt; </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">button</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addEventListener</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;click&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk4\">async</span><span class=\"mtk1\">() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">display</span><span class=\"mtk1\">.</span><span class=\"mtk12\">textContent</span><span class=\"mtk1\">= </span><span class=\"mtk8\">&#39;&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">user</span><span class=\"mtk1\">[</span><span class=\"mtk12\">i</span><span class=\"mtk1\">+</span><span class=\"mtk7\">1</span><span class=\"mtk1\">].</span><span class=\"mtk12\">id</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/api/auth/update&#39;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">method:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;PUT&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">body:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">role:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;admin&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">id</span><span class=\"mtk1\">}),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> { </span><span class=\"mtk8\">&#39;Content-Type&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk1\"> }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">dataUpdate</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> === </span><span class=\"mtk7\">400</span><span class=\"mtk1\"> || </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> === </span><span class=\"mtk7\">401</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\">.</span><span class=\"mtk12\">scrollTop</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">0</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk12\">documentElement</span><span class=\"mtk1\">.</span><span class=\"mtk12\">scrollTop</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">0</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">display</span><span class=\"mtk1\">.</span><span class=\"mtk12\">textContent</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">`</span><span class=\"mtk4\">${</span><span class=\"mtk12\">dataUpdate</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk4\">}</span><span class=\"mtk8\">. </span><span class=\"mtk4\">${</span><span class=\"mtk12\">dataUpdate</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk1\"> ? </span><span class=\"mtk12\">dataUpdate</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk1\"> : </span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">location</span><span class=\"mtk1\">.</span><span class=\"mtk11\">assign</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/admin&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">}</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h3 id=\"delete-users\" style=\"position:relative;\"><a href=\"#delete-users\" aria-label=\"delete users permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Delete Users</h3>\n<p>Deleting Users from the database should be the duty of an admin.</p>\n<p><code>admin.ejs</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"54\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ...</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  const editRole = document.querySelectorAll(&#39;.edit&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  const deleteUser = document.querySelector(&#39;.delete&#39;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  deleteUser.forEach((button, i)=&gt; </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk12\">button</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addEventListener</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;click&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> ()</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk12\">display</span><span class=\"mtk1\">.</span><span class=\"mtk12\">textContent</span><span class=\"mtk1\"> =</span><span class=\"mtk8\">&#39;&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">user</span><span class=\"mtk1\">[</span><span class=\"mtk12\">i</span><span class=\"mtk1\">+</span><span class=\"mtk7\">1</span><span class=\"mtk1\">].</span><span class=\"mtk12\">id</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/api/auth/deleteUser&#39;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk12\">method:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;DELETE&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk12\">body:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">({</span><span class=\"mtk12\">id</span><span class=\"mtk1\">}),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> {</span><span class=\"mtk8\">&#39;Content-Type&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">dataDelete</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> === </span><span class=\"mtk7\">401</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\">.</span><span class=\"mtk12\">scrollTop</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">0</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk12\">documentElement</span><span class=\"mtk1\">.</span><span class=\"mtk12\">scrollTop</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">0</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">display</span><span class=\"mtk1\">.</span><span class=\"mtk12\">textContent</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">`</span><span class=\"mtk4\">${</span><span class=\"mtk12\">dataUpdate</span><span class=\"mtk1\">.</span><span class=\"mtk12\">message</span><span class=\"mtk4\">}</span><span class=\"mtk8\">. </span><span class=\"mtk4\">${</span><span class=\"mtk12\">dataUpdate</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk1\"> ? </span><span class=\"mtk12\">dataUpdate</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk1\"> : </span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk12\">location</span><span class=\"mtk1\">.</span><span class=\"mtk11\">assign</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/admin&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">}</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>You've created an event listener that listens for a click on the <code>Delete User</code> button. When the button is clicked, you'll send a <code>DELETE</code> request to <code>/api/auth/deleteUser</code>.</p>\n<blockquote>\n<p>Please ensure the admin user is first on the list to avoid populating the database with an admin user again.</p>\n</blockquote>\n<h2 id=\"logout-functionality\" style=\"position:relative;\"><a href=\"#logout-functionality\" aria-label=\"logout functionality permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Logout Functionality</h2>\n<p>To log out users, you need to remove the token from the client and redirect the client to the home page.</p>\n<p>You'll create a <code>GET</code> request to <code>/logout</code> in the <code>server.js</code> file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"55\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/logout&quot;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">cookie</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;jwt&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">, { </span><span class=\"mtk12\">maxAge:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;1&quot;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">redirect</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span></code></pre>\n<p>The code snippet replaced the JWT token with an empty string and gave it a lifespan of 1 second.</p>\n<p>After creating the <code>GET</code> request, add a logout button to the admin's route and user's route:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"56\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">ul</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">ul</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;logout&quot;</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/logout&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Log Out</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">a</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span></code></pre>\n<h2 id=\"nodejs-authentication-with-loginradius\" style=\"position:relative;\"><a href=\"#nodejs-authentication-with-loginradius\" aria-label=\"nodejs authentication with loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Node.js Authentication with LoginRadius</h2>\n<p>You can simply replace the many steps discussed above using <a href=\"https://www.loginradius.com/docs/api/v2/getting-started/introduction/\">LoginRadius</a>. In turn, it helps you focus more on developing core application features while letting you quickly implement user signup and login and manager users.</p>\n<p>In other words, LoginRadius is a SaaS-based customer identity and access management (CIAM) system with features to manage customer identity, privacy, and access. It is a simple, implementable solution for adding user authentication and authorization to your website.</p>\n<p>Basically, LoginRadius handles user registration, login, and authentication. Other features of LoginRadius include:</p>\n<ul>\n<li><strong>Forms</strong>: LoginRadius can automatically pre-create registration and login forms for you.</li>\n<li><strong>Authentication and Authorization</strong>: It generates and sends a token to the user when login or signup is successful. Instead of using <code>JWT</code>, you can use this token to authenticate users</li>\n<li><strong>Security</strong>: When using LoginRadius, you automatically have access to an admin console where you can control authentication factors, such as email, phone, and multi-factor auth for your Node.js app.</li>\n</ul>\n<p>To get started with LoginRadius, you need to <a href=\"https://accounts.loginradius.com/auth.aspx\">create an account</a> with either the free plan or the Developer plan, customize your registration and login forms, and start managing your users.</p>\n<h3 id=\"how-to-authenticate-your-nodejs-app-with-loginradius\" style=\"position:relative;\"><a href=\"#how-to-authenticate-your-nodejs-app-with-loginradius\" aria-label=\"how to authenticate your nodejs app with loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to Authenticate Your Node.js App with LoginRadius</h3>\n<p>This section briefly covers how authentication works with LoginRadius.</p>\n<p>After signing up for LoginRadius, choose a name for your Node.js app.</p>\n<blockquote>\n<p><img src=\"/faed37adab3b93cbf078cb49970ff8a6/loginradius.webp\" alt=\"LoginRadius - Enter your app name\"></p>\n</blockquote>\n<p>After completing your LoginRadius signup process, you can get your <strong>App Name</strong>, <strong>API Key</strong>, and <strong>API Secret</strong> from the <code>configuration</code> link on the sidebar. With these configurations, you can easily link the server-side of our application to LoginRadius.</p>\n<p><img src=\"/3c5de91ef87963f5ea96eb10556ba358/loginradius1.webp\" alt=\"LoginRadius API Credentials\"></p>\n<p>LoginRadius automatically generates a link that will be used to authenticate users. This link contains the name of your LoginRadius application and a <code>URL</code> that authenticated users will be redirected to:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"57\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">https://&lt;LoginRadius-APP-Name&gt;.hub.loginradius.com/auth.aspx?action=login&return_url=&lt;Return-URL&gt;</span></code></pre>\n<p>An instance of the link is given below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"58\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">https://noderoleauth.hub.loginradius.com/auth.aspx?action=login&return_url=http://localhost:5000</span></code></pre>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>You've successfully learned how to perform CRUD operations using MongoDB as a database, hash passwords, authenticate using JWT, and render Embedded JavaScript (EJS). You can put all these together to build more complex applications.</p>\n<h2 id=\"resources\" style=\"position:relative;\"><a href=\"#resources\" aria-label=\"resources permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Resources</h2>\n<ul>\n<li>A full, working version of <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/NodeJs/NodejsAuthenticationGuide\">the code used in this tutorial is available on GitHub</a></li>\n<li><a href=\"https://www.loginradius.com/developers/\">Node.js Authentication with LoginRadius</a></li>\n</ul>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk17 { color: #808080; }\n</style>","frontmatter":{"date":"January 18, 2022","updated_date":null,"title":"Node.js User Authentication Guide","tags":["JWT","Authentication","Node.js"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.9047619047619047,"src":"/static/36e3e372636f4119a2bf4ee3878592ae/58556/coverimage.webp","srcSet":"/static/36e3e372636f4119a2bf4ee3878592ae/61e93/coverimage.webp 200w,\n/static/36e3e372636f4119a2bf4ee3878592ae/1f5c5/coverimage.webp 400w,\n/static/36e3e372636f4119a2bf4ee3878592ae/58556/coverimage.webp 800w,\n/static/36e3e372636f4119a2bf4ee3878592ae/bfd1f/coverimage.webp 1034w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Uma Victor","github":"uma-victor1","avatar":null}}}},{"node":{"fields":{"slug":"/engineering/guest-post/local-storage-vs-session-storage-vs-cookies/"},"html":"<p>In this post, I’ll talk about how cookies compare to browser storage. You’ll understand why cookies came out, the problem they solve, and their limitations.</p>\n<p>Then you’ll explore what browser storage is, and dive deeper into local storage and session storage. You’ll look at their features, where they can be useful, and how to use them via JavaScript.</p>\n<p>You’ll then see how you can contrast the features, advantages, and disadvantages of each and also highlight specific use cases of each.</p>\n<p>You’ll also look at the best practices or approach to keep in mind while using each of them and the best place to store your JWT or auth tokens.</p>\n<hr>\n<p>How many times have you seen a popup on a website that says:</p>\n<blockquote>\n<p>This website is using cookies to store your information.</p>\n</blockquote>\n<p>I'm guessing so often that you've lost the count!</p>\n<p>Cookies have been used since time immemorial for storing session related information of a user. This allows websites to provide a unique and engaging experience to their users.</p>\n<p>However, cookies can be a bit difficult to use, have limited use-case, and have small data storing capacity. To combat this, modern browsers come with their own storage mechanisms like local storage and session storage.</p>\n<p>In this post, I’ll talk about these storage mechanisms. You'll understand how local storage, session storage, and cookies compare against one another and explore common use cases of each. By the end of this post, you'll know exactly when to use which.</p>\n<h2 id=\"a-brief-history-of-cookies\" style=\"position:relative;\"><a href=\"#a-brief-history-of-cookies\" aria-label=\"a brief history of cookies permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>A Brief History of Cookies</h2>\n<p>Let's have a refresher on the history of cookies.</p>\n<p>Back in the day, websites used HTTP protocol which is <em>stateless</em>. This meant that they couldn't store user-related information like the user’s session id, the name of the user, etc., in the browser.</p>\n<p>As the web advanced and grew more popular, websites started storing user related information in the browser itself. This helped them differentiate what kind of user is interacting with their website and provide a personalized experience to the user.</p>\n<h3 id=\"enter-cookies\" style=\"position:relative;\"><a href=\"#enter-cookies\" aria-label=\"enter cookies permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Enter Cookies</h3>\n<p>That's how cookies were born. They presented a mechanism to store lightweight client or server side data on the browser as key value pairs. They also had an expiry timestamp after which they were automatically deleted by the browser.</p>\n<p>Also, both browser and the server could set and retrieve cookies from a user’s browser. Moreover, these cookies were sent alongside each HTTP request automatically. This came in handy for server side websites at a time when single page applications weren't a thing. They could easily discern a user's information with each HTTP request that user made.</p>\n<h2 id=\"the-rise-of-browser-storage\" style=\"position:relative;\"><a href=\"#the-rise-of-browser-storage\" aria-label=\"the rise of browser storage permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The Rise of Browser Storage</h2>\n<p>Where cookies solved a great problem, it had some limitations. First, they could only store data up to a few kbs. As client-side applications became more complex, there was a need to store more complex data in the browser.</p>\n<p>With the onset of HTML5, websites were introduced to browser storage APIs for storing client side information. These APIs were available on browser's window objects globally. Thus, any JavaScript running in the browser could easily access them. The major differentiator was that they had higher data storage capacity and could only be accessed by client-side JavaScript.</p>\n<p>Browsers rolled out two storage mechanisms — local storage and session storage. So let's explore and understand them in detail.</p>\n<h2 id=\"browsers-session-storage\" style=\"position:relative;\"><a href=\"#browsers-session-storage\" aria-label=\"browsers session storage permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Browser’s Session Storage</h2>\n<p>Let's first take a peek at where the session storage resides in the browser:</p>\n<ol>\n<li>\n<p>Open the developer tools in the browser and head over to the \"Application\" tab.</p>\n<p><img src=\"/0ebf0cdf4a93f440703feca7905c12d7/application-tab-screenshot.webp\" alt=\"Application Tab Screenshot\"></p>\n</li>\n<li>\n<p>Under the storage section, you'll find a section named \"Session Storage\".</p>\n<p><img src=\"/06434490c7d0ce18eb26570b842e3c03/session-storage-tab-screenshot.webp\" alt=\"Session Storage Section Screenshot\"></p>\n</li>\n<li>Click on it, and you'll be able to see the session storage for that website.</li>\n</ol>\n<p>There it is! Now, let's look at the features of browser's session storage.</p>\n<h3 id=\"storage-capacity\" style=\"position:relative;\"><a href=\"#storage-capacity\" aria-label=\"storage capacity permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Storage Capacity</h3>\n<p>Session storage can store data ranging between 5mb - 10mb. The exact amount of storage capacity varies as per each browser's implementation, but it's a lot more than 4kb of storage capacity cookies offer!</p>\n<h3 id=\"data-persistence\" style=\"position:relative;\"><a href=\"#data-persistence\" aria-label=\"data persistence permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Data Persistence</h3>\n<p>As the name suggests, session storage only persists the data as long as a browser tab is opened. This means that each time you open a new tab or a new browser window, a new session storage is created. So any data you store inside the session storage will automatically get deleted when you close that tab/window.</p>\n<h3 id=\"using-session-storage\" style=\"position:relative;\"><a href=\"#using-session-storage\" aria-label=\"using session storage permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Using Session Storage</h3>\n<p>You can access the session storage in the <code>window</code> object:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">window</span><span class=\"mtk1\">.</span><span class=\"mtk12\">sessionStorage</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//Storage {length: 0}</span></span></code></pre>\n<p>This would return the length of the session storage along with an object representing the data that's currently present inside. Since it's empty to begin with, the length is 0. Note that you may directly access the <code>sessionStorage</code> object as well.</p>\n<h4 id=\"adding-data\" style=\"position:relative;\"><a href=\"#adding-data\" aria-label=\"adding data permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Adding Data</h4>\n<p>Let's add a key-value pair to the session storage using the <code>setItem</code> function available in the <code>sessionStorage</code> object:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">sessionStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;id&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;123&quot;</span><span class=\"mtk1\">)</span></span></code></pre>\n<p>This will set a new item in the session storage with the key <code>id</code> and value <code>123</code>. If you simply invoke the <code>sessionStorage</code> object now:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">sessionStorage</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//Storage {id: &#39;123&#39;, length: 1}</span></span></code></pre>\n<p>You now get your recently added data back!</p>\n<p>You'll also see this inside the session storage section of the browser's application tab:</p>\n<p><img src=\"/b1a0553ff05f85ebaf162682253e4b26/session-storage-example-1.webp\" alt=\"Session Storage Example\"></p>\n<h4 id=\"inserting-complex-json-data\" style=\"position:relative;\"><a href=\"#inserting-complex-json-data\" aria-label=\"inserting complex json data permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Inserting Complex JSON Data</h4>\n<p>Let's add a bit more complex JSON object in the session storage that looks like this:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">data</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">_id:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;61c6c1df7cda7d370a9ef601&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">index:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">guid:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;13672f0e-f693-4704-a6f9-839ff36e8960&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">isActive:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">balance:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;$3,602.49&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">picture:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;http://placehold.it/32x32&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">age:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">25</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">friends:</span><span class=\"mtk1\"> [</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Adkins Coleman&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">1</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Howe Douglas&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">2</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Becky Velez&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>You'll first need to <em>stringify</em> it since the value against a key can only be a string. Then, you'll store it inside the session storage using the <code>setItem</code> method:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">sessionStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;user_data&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\">))</span></span></code></pre>\n<p>It should now appear inside the session storage of the browser's application tab:</p>\n<p><img src=\"/f50ac32714fdfb933b604c04ba24e30b/session-storage-example-2.webp\" alt=\"Complex JSON Data in Session Storage Example\"></p>\n<p>Awesome! Let's take a look at retrieving this data.</p>\n<h4 id=\"retrieving-data\" style=\"position:relative;\"><a href=\"#retrieving-data\" aria-label=\"retrieving data permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Retrieving Data</h4>\n<p>You can use the <code>getItem()</code> function to retrieve a value stored against a key from the session storage by specifying the key as the first parameter in the function.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">sessionStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;id&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//&#39;123&#39;</span></span></code></pre>\n<p>If you're retrieving an object, you'll need to use <code>JSON.parse</code> first to convert the string into a JavaScript object:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">parse</span><span class=\"mtk1\">(</span><span class=\"mtk12\">sessionStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;user_data&quot;</span><span class=\"mtk1\">))</span></span></code></pre>\n<h3 id=\"usecase\" style=\"position:relative;\"><a href=\"#usecase\" aria-label=\"usecase permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Usecase</h3>\n<p>Since data in session storage persists only across a browser tab, there are some unique usecases for session storage.</p>\n<h4 id=\"booking-applications\" style=\"position:relative;\"><a href=\"#booking-applications\" aria-label=\"booking applications permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Booking Applications</h4>\n<p>Session storage can be used in multi-step processes that must be performed in a single instance. This includes booking flights, hotels, movie tickets, train reservations etc. You can store the details of the previous steps in the browser's session storage to prepopulate those forms or inputs.</p>\n<p>Since these are critical activities that must be performed in a single go, the data will automatically get deleted when the user jumps to a new tab or a new browser window.</p>\n<h4 id=\"prompting-loginsignups-to-a-user\" style=\"position:relative;\"><a href=\"#prompting-loginsignups-to-a-user\" aria-label=\"prompting loginsignups to a user permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Prompting Login/Signups to a User</h4>\n<p>Blogging websites, newsletters, tutorial websites etc., have tons of visitors who read through the content without creating an account. In such scenarios, you can subtly prompt the user every time they visit the website to create an account. You can track the session of each user in the session storage.</p>\n<p>Every time a user reads a blog post or an article on a different tab, you can ask them to create an account. This could be a great way to offer a non-blocking experience for your users whilst effectively converting them to a signed-up user for your website.</p>\n<h2 id=\"browsers-local-storage\" style=\"position:relative;\"><a href=\"#browsers-local-storage\" aria-label=\"browsers local storage permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Browser’s Local Storage</h2>\n<p>Under the application tab where session storage resides, you'll find a section called local storage right underneath it.</p>\n<p><img src=\"/416bc127a50f7d6d1aa5f726c5fe32d8/local-storage-tab-screenshot.webp\" alt=\"Local Storage Tab Screenshot\"></p>\n<p>That's where you can see everything you store inside the local storage of your browser. Local storage works, appears, and similar to session storage. For instance, just like Session storage, local storage can also store data ranging between 5mb - 10mb depending upon a browser's implementation.</p>\n<h3 id=\"data-persistence-1\" style=\"position:relative;\"><a href=\"#data-persistence-1\" aria-label=\"data persistence 1 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Data Persistence</h3>\n<p>Unlike session storage where data is automatically deleted when a browser tab or window is closed, data in local storage has no default expiry. It's only deleted if you manually delete that data from the local storage either directly, via browser settings, or through your JavaScript code.</p>\n<p>That means that data in a local storage persists even after a particular tab or browser window is closed.</p>\n<h3 id=\"using-local-storage\" style=\"position:relative;\"><a href=\"#using-local-storage\" aria-label=\"using local storage permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Using Local Storage</h3>\n<p>You can add and retrieve data from local storage in the same way you perform those operations with session storage. The only change is now you'll have to use the <code>localStorage</code> object to perform these operations instead.</p>\n<p>For instance, you can add an item to the <code>localStorage</code>, as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">localStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;id&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;123&quot;</span><span class=\"mtk1\">)</span></span></code></pre>\n<p>Consequently, you can retrieve an item using the <code>getItem()</code> function:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">localStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;id&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//&#39;123&#39;</span></span></code></pre>\n<h3 id=\"usecase-1\" style=\"position:relative;\"><a href=\"#usecase-1\" aria-label=\"usecase 1 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Usecase</h3>\n<p>Local storage has a number of uses due to the fact that data inside it has no default expiry. Think about all those scenarios where you want to store some global data that's accessed often in your application.</p>\n<h4 id=\"generic\" style=\"position:relative;\"><a href=\"#generic\" aria-label=\"generic permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Generic</h4>\n<p>For instance, your user's email id, username, full-name, etc. All these data are widely used throughout different pages of your application. Storing this data inside the local storage will help you prevent unwanted API calls to the server to fetch this data. Also, since this data isn't normally changed often, the chances of having inconsistent data across the browser and the server is quite low.</p>\n<h4 id=\"application-specific\" style=\"position:relative;\"><a href=\"#application-specific\" aria-label=\"application specific permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Application Specific</h4>\n<p>You can also use it to store application specific data that is immutable throughout a login session of a user. For instance, if you have an ecommerce site, you can store the preferred payment option of the user, default delivery addresses, etc. You can also store user preferences such as the theme a user prefers for your website (dark or light mode).</p>\n<h2 id=\"cookies-vs-browser-storage\" style=\"position:relative;\"><a href=\"#cookies-vs-browser-storage\" aria-label=\"cookies vs browser storage permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Cookies vs. Browser Storage</h2>\n<p>Now that you've understand how browser storage works, you can compare them effectively against cookies. However, let's first look at their similarities.</p>\n<h3 id=\"similarities\" style=\"position:relative;\"><a href=\"#similarities\" aria-label=\"similarities permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Similarities</h3>\n<p>Remember in the beginning I asked you how many times you've seen that cookies popup? Most of these popups also have an option where you can choose not to accept these cookies.</p>\n<p>In other words, cookies are <em>blockable</em> by users and so is browser storage. Users can choose not to allow their data to be stored via any of these mechanisms — and hence, your application should never completely rely on these storage mechanisms.</p>\n<p>Both cookies and browser storage store key-value pairs as strings and are well supported in all modern browsers. The data inside this can also be easily edited by the user.</p>\n<h3 id=\"differences\" style=\"position:relative;\"><a href=\"#differences\" aria-label=\"differences permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Differences</h3>\n<p>You know that browser storage has a greater storage capacity than cookies. Hence, browser storage is always a better choice than cookies to store large client-side data.</p>\n<p>However, since session storage and local storage have different data persistence, you should carefully choose either of them depending on how long you want the data to persist.</p>\n<p>Cookies allow you to automatically set a TTL or expiry time; are transferred with every HTTP request to the server; and, can also be accessed by the server. These features are missing in browser storage. Which brings us to the question — where would cookies be actually more useful than browser storage?</p>\n<p><img src=\"/e8316b6440c807470cda0e44ad49aede/comparison-table.webp\" alt=\"Comparison Table of Local Storage Session Storage and Cookies\"></p>\n<p>The answer is server side data! If you've dealt with authentication before, you know that at some point you need to store the authentication token or JWT of a user somewhere where it's easily accessible. That's where cookies are helpful. But why can't we use or why shouldn't we use browser storage here?</p>\n<h2 id=\"storing-your-jwtauth-token\" style=\"position:relative;\"><a href=\"#storing-your-jwtauth-token\" aria-label=\"storing your jwtauth token permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Storing Your JWT/Auth Token</h2>\n<p>Data such as JWT or Auth token should not be stored in browser storage because they can be accessed by any client side JavaScript running in the browser. This means that if your application somehow leaves an XSS vulnerability, your user's authentication token could be easily leaked to the attacker.</p>\n<p>The attacker could then make false requests, modify your user's data in the database, and do a lot of damage for your application as well as users. Hence, it's always best to store JWTs in http only cookies. Http only cookies are special cookies that cannot be accessed by client side JavaScript. This way they're secure against XSS attacks.</p>\n<p>Also, authentication token is often refreshed on expiry and one can use cookies TTL easily to manage that. For simpler cases, one can also store JWT inside regular cookies by setting a TTL.</p>\n<p>But all in all, authentication itself can be a tricky subject. If you're looking for a no-code identity platform that can seamlessly handle authentication for your application, consider using <a href=\"https://www.loginradius.com/\">LoginRadius</a>.</p>\n<h2 id=\"wrapping-it-up\" style=\"position:relative;\"><a href=\"#wrapping-it-up\" aria-label=\"wrapping it up permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Wrapping it Up</h2>\n<p>Now that you understand how powerful browser storage is, don't feel shy to use it in your applications. Use cookies for server side data where you need a TTL, session storage for specific use cases discussed above, and local storage to manage global data in your application.</p>\n<p>However, avoid the pattern where your single page application directly interacts with the local storage. For instance, if you're using React with Redux to manage the state in your application, let your reducers take control over what goes and comes out of local storage. Your React components should be abstracted from using local storage directly.</p>\n<p>Finally, since local storage data has no default expiry, be vary of when you're clearing this data to avoid data inconsistency between your frontend and backend.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n</style>","frontmatter":{"date":"January 12, 2022","updated_date":null,"title":"Local Storage vs. Session Storage vs. Cookies","tags":["Cookie","Browser Storage","Authentication","JWT"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/e9788df6bdd55f91b1eccb4382f05573/58556/blog-banner.webp","srcSet":"/static/e9788df6bdd55f91b1eccb4382f05573/61e93/blog-banner.webp 200w,\n/static/e9788df6bdd55f91b1eccb4382f05573/1f5c5/blog-banner.webp 400w,\n/static/e9788df6bdd55f91b1eccb4382f05573/58556/blog-banner.webp 800w,\n/static/e9788df6bdd55f91b1eccb4382f05573/99238/blog-banner.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Siddhant Varma","github":"FuzzySid","avatar":null}}}},{"node":{"fields":{"slug":"/engineering/guest-post/securing-php-api-with-jwt/"},"html":"<p>Security has become a fundamental aspect to consider while developing an application. As people become more aware and hackers more notorious, you need to employ systems that strengthen your application's data security.</p>\n<p>Previously, it was common to use session storage to secure applications. In recent times, sessions have proved inefficient, which pushed to migrate to authentication with APIs. Even though this was a superb and robust way to secure web applications, it became obsolete as hackers tried to figure out how to crack this authentication.</p>\n<p>As the web evolves to accept more and more users, the research for secure authentication techniques speeds up. In 2010, the world was introduced to a new and secure authentication standard -- JWT. Let's know more about JWT.</p>\n<h2 id=\"what-is-jwt\" style=\"position:relative;\"><a href=\"#what-is-jwt\" aria-label=\"what is jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is JWT?</h2>\n<p>JSON Web Token (JWT) is a safe way to authenticate users on a web app. Using JWT, you can securely transfer encrypted data and information between a client computer and a server.</p>\n<blockquote>\n<p>Learn more about the <a href=\"https://www.loginradius.com/blog/engineering/guest-post/jwt-vs-sessions/\">differences between sessions and JWTs here</a>.</p>\n</blockquote>\n<p>JWT offers many benefits. Here are some of them.</p>\n<h2 id=\"benefits-of-using-jwt\" style=\"position:relative;\"><a href=\"#benefits-of-using-jwt\" aria-label=\"benefits of using jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Benefits of Using JWT</h2>\n<ul>\n<li>Compatible with OAuth 2, meaning your applications will be easy to work with the latest security standards.</li>\n<li>JWTs can expire after some time so that no one has uninterrupted access to the website. This is important to protect a website from attacks.</li>\n<li>JSON is used to transmit data, so you can work with any language of your choice and handle the JSON data.</li>\n<li>JWTs are feature-rich and encompass complete information about any authorization request with different aspects.</li>\n</ul>\n<p>Now that you've learned about the advantages, it's time to go deeper into the JWT.</p>\n<h2 id=\"the-structure-of-jwt\" style=\"position:relative;\"><a href=\"#the-structure-of-jwt\" aria-label=\"the structure of jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The Structure of JWT</h2>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"json\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">eyJ</span><span class=\"mtk7\">0</span><span class=\"mtk1\">eXAiOiJKV</span><span class=\"mtk7\">1</span><span class=\"mtk1\">QiLCJhbGciOiJIUzI</span><span class=\"mtk7\">1</span><span class=\"mtk1\">NiJ</span><span class=\"mtk7\">9</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  .eyJpc</span><span class=\"mtk7\">3</span><span class=\"mtk1\">MiOiJodHRwczpcL</span><span class=\"mtk7\">1</span><span class=\"mtk1\">wvcWEtYXBpLndlbGx</span><span class=\"mtk7\">2</span><span class=\"mtk1\">aWJlLmNvbVwvYXBpXC</span><span class=\"mtk7\">9</span><span class=\"mtk1\">hdXRoXC</span><span class=\"mtk7\">9</span><span class=\"mtk1\">sb</span><span class=\"mtk7\">2</span><span class=\"mtk1\">dpbiIsImlhdCI</span><span class=\"mtk7\">6</span><span class=\"mtk1\">MTYzMDQ</span><span class=\"mtk7\">3</span><span class=\"mtk1\">OTA</span><span class=\"mtk7\">5</span><span class=\"mtk1\">NSwiZXhwIjoxNjMwNDgyNjk</span><span class=\"mtk7\">1</span><span class=\"mtk1\">LCJuYmYiOjE</span><span class=\"mtk7\">2</span><span class=\"mtk1\">MzA</span><span class=\"mtk7\">0</span><span class=\"mtk1\">NzkwOTUsImp</span><span class=\"mtk7\">0</span><span class=\"mtk1\">aSI</span><span class=\"mtk7\">6</span><span class=\"mtk1\">Imtsa</span><span class=\"mtk7\">3</span><span class=\"mtk1\">hHUGpMOVlNTzRSdUsiLCJzdWIiOjc</span><span class=\"mtk7\">3</span><span class=\"mtk1\">ODE</span><span class=\"mtk7\">4</span><span class=\"mtk1\">LCJwcnYiOiIyM</span><span class=\"mtk7\">2</span><span class=\"mtk1\">JkNWM</span><span class=\"mtk7\">4</span><span class=\"mtk1\">OTQ</span><span class=\"mtk7\">5</span><span class=\"mtk1\">ZjYwMGFkYjM</span><span class=\"mtk7\">5</span><span class=\"mtk1\">ZTcwMWM</span><span class=\"mtk7\">0</span><span class=\"mtk1\">MDA</span><span class=\"mtk7\">4</span><span class=\"mtk1\">NzJkYjdhNTk</span><span class=\"mtk7\">3</span><span class=\"mtk1\">NmY</span><span class=\"mtk7\">3</span><span class=\"mtk1\">IiwidXNlcnNfaWQiOjc</span><span class=\"mtk7\">3</span><span class=\"mtk1\">ODE</span><span class=\"mtk7\">4</span><span class=\"mtk1\">LCJtZW</span><span class=\"mtk7\">1</span><span class=\"mtk1\">iZXJzX</span><span class=\"mtk7\">2</span><span class=\"mtk1\">lkIjo</span><span class=\"mtk7\">3</span><span class=\"mtk1\">Nzg</span><span class=\"mtk7\">4</span><span class=\"mtk1\">MzMsInByb</span><span class=\"mtk7\">3</span><span class=\"mtk1\">h</span><span class=\"mtk7\">5</span><span class=\"mtk1\">X</span><span class=\"mtk7\">3</span><span class=\"mtk1\">VzZXJfbWVtYmVyc</span><span class=\"mtk7\">19</span><span class=\"mtk1\">pZCI</span><span class=\"mtk7\">6</span><span class=\"mtk1\">bnVsbH</span><span class=\"mtk7\">0</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  .TxXwLLu</span><span class=\"mtk7\">1</span><span class=\"mtk1\">zWBe</span><span class=\"mtk7\">7</span><span class=\"mtk1\">cLLYdFYy</span><span class=\"mtk7\">3</span><span class=\"mtk1\">P</span><span class=\"mtk7\">2</span><span class=\"mtk1\">HX</span><span class=\"mtk7\">4</span><span class=\"mtk1\">AaLgc</span><span class=\"mtk7\">7</span><span class=\"mtk1\">WfSRtTgeiI</span></span></code></pre>\n<p>The above string is an example of a JWT authentication string. At first glance, it may appear to be a randomly produced string. But don't underestimate; this string is made up of three separate components that are essential in a JWT.</p>\n<h3 id=\"jwt-header\" style=\"position:relative;\"><a href=\"#jwt-header\" aria-label=\"jwt header permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>JWT Header</h3>\n<p>The header of a JWT is the initial section of the string before the first dot. This header is produced by acquiring plain text and performing cryptographic operations on it. Moreover, the header uses a very efficient Base64 encoding procedure.</p>\n<p>You can quickly obtain the JWT's headers using symmetric or asymmetric encryption techniques.</p>\n<h3 id=\"jwt-payload\" style=\"position:relative;\"><a href=\"#jwt-payload\" aria-label=\"jwt payload permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>JWT Payload</h3>\n<p>The string's central component is the JWT's payload part. This string includes all of the important information about a received request and the user or client computer who created the request. There are predefined key-value pair fields in the payload that can be used to offer extra information about the received request. Here is an explanation of common payload fields.</p>\n<ul>\n<li><strong>Sub</strong> - The sub field contains the subject of a JWT payload. It contains unique information about the user and client device that has created this authentication request.</li>\n<li><strong>Iss</strong> - This field contains data about the server that has issued the token. Iss is short for Issuer, which refers to the server.</li>\n<li><strong>Exp</strong> - Unlike other authentication techniques, JWT has an expiration time. This field's name is a short form for the expiration date. It contains data about when the token was issued and the expiration date and time of the issued token.</li>\n</ul>\n<h3 id=\"jwt-signature\" style=\"position:relative;\"><a href=\"#jwt-signature\" aria-label=\"jwt signature permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>JWT Signature</h3>\n<p>A cryptographic operation is performed on the JWT data to obtain this signature. It takes in the payload, secret key, and header value of a JWT. The signature is then generated by applying a function to these obtained values.</p>\n<p>The server and user can verify this signature to know about the data's security and integrity. If this signature matches at both ends, then the data is considered secure, and all other transactions can occur.</p>\n<h2 id=\"using-jwts-to-secure-php-api\" style=\"position:relative;\"><a href=\"#using-jwts-to-secure-php-api\" aria-label=\"using jwts to secure php api permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Using JWTs to Secure PHP API</h2>\n<p>As you've understood everything about JWT, let's secure your PHP API using JWT. Follow the code along, and, in the end, you'll create a tamper-proof PHP API.</p>\n<p>This article creates a simple login page and authenticates it using JWT. This will help you get started with JWT and PHP.</p>\n<p>To follow along, you'll need to have PHP and composer installed on your computer.</p>\n<p>If you haven't already installed composer on your computer, you can <a href=\"https://getcomposer.org/doc/00-intro.md\">learn how to install composer here</a>. Once you've installed composer, run the tool from your project folder. Composer will assist you in installing Firebase PHP-JWT, a third-party library for working with JWTs and Apache.</p>\n<p>Once the library is installed, you'll need to set up a login code in <code>authenticate.php</code>. While you do this, put a code piece that checks and gets the autoloader from the composer tool. The below code helps you achieve this.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;?php</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">declare</span><span class=\"mtk1\">(strict_types=</span><span class=\"mtk7\">1</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">use</span><span class=\"mtk1\"> Firebase\\JWT\\</span><span class=\"mtk10\">JWT</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">require_once</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;../vendor/autoload.php&#39;</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>When the form gets submitted, you need to check the entered data with a data source or database. For our purpose, let's create a <code>hasValidCredentials</code> variable and set it to true. Setting this variable to true means that the data is checked and valid.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;?php</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// extract credentials from the request</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">$hasValidCredentials</span><span class=\"mtk1\">) {</span></span></code></pre>\n<p>Any further coding will be wrapped in this block itself. The value of the <code>hasValidCredentials</code> variable governs all code related to the production and validation of the required JWT. If its value is true, the JWT shall be created; otherwise, an error will be shown.</p>\n<h3 id=\"creating-jwt\" style=\"position:relative;\"><a href=\"#creating-jwt\" aria-label=\"creating jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Creating JWT</h3>\n<p>Let's start creating the JWT. First, you need to generate some more variables to aid in this process. As you saw in the payload section, you must create:</p>\n<ul>\n<li>a variable that will hold the secret key, which may be retrieved from the environment files;</li>\n<li>another variable to hold information about when the JWT was created;</li>\n<li>a variable that will hold the JWT's expiration date and time;</li>\n<li>a username field to identify the client making the authorization request; and,</li>\n<li>a server name variable to register the server name.</li>\n</ul>\n<p>JWT's can be easily inspected and checked at client-side browsers. So it is better to hide your secret key and other important information in some environment file, which the user cannot access through client-side requests.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">$secret_Key</span><span class=\"mtk1\">  = </span><span class=\"mtk8\">&#39;68V0zWFrS72GbpPreidkQFLfj4v9m3Ti+DXc8OB0gcM=&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$date</span><span class=\"mtk1\">   = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">DateTimeImmutable</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$expire_at</span><span class=\"mtk1\">     = </span><span class=\"mtk12\">$date</span><span class=\"mtk1\">-&gt;</span><span class=\"mtk11\">modify</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;+6 minutes&#39;</span><span class=\"mtk1\">)-&gt;</span><span class=\"mtk11\">getTimestamp</span><span class=\"mtk1\">();      </span><span class=\"mtk3\">// Add 60 seconds</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$domainName</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;your.domain.name&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$username</span><span class=\"mtk1\">   = </span><span class=\"mtk8\">&quot;username&quot;</span><span class=\"mtk1\">;                                           </span><span class=\"mtk3\">// Retrieved from filtered POST data</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$request_data</span><span class=\"mtk1\"> = [</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;iat&#39;</span><span class=\"mtk1\">  =&gt; </span><span class=\"mtk12\">$date</span><span class=\"mtk1\">-&gt;</span><span class=\"mtk11\">getTimestamp</span><span class=\"mtk1\">(),         </span><span class=\"mtk3\">// Issued at: time when the token was generated</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;iss&#39;</span><span class=\"mtk1\">  =&gt; </span><span class=\"mtk12\">$domainName</span><span class=\"mtk1\">,                       </span><span class=\"mtk3\">// Issuer</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;nbf&#39;</span><span class=\"mtk1\">  =&gt; </span><span class=\"mtk12\">$date</span><span class=\"mtk1\">-&gt;</span><span class=\"mtk11\">getTimestamp</span><span class=\"mtk1\">(),         </span><span class=\"mtk3\">// Not before</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;exp&#39;</span><span class=\"mtk1\">  =&gt; </span><span class=\"mtk12\">$expire_at</span><span class=\"mtk1\">,                           </span><span class=\"mtk3\">// Expire</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;userName&#39;</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk12\">$username</span><span class=\"mtk1\">,                     </span><span class=\"mtk3\">// User name</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">];</span></span></code></pre>\n<p>Now you have all the required data in hand; you can easily create a JWT. Here, you'll use the PHP-JWT package's <code>encode()</code> method. This method helps transform your data array into a JSON object.</p>\n<p>Following the conversion to a JSON object, the encode function produces JWT headers and signs the received payload with a cryptographic combination of all the information and the given secret key.</p>\n<p>It is essential to supply three arguments to the <code>encode()</code> method to utilize it correctly. The first argument should be the payload information, which is the data array in this instance. Secondly, you must supply the secret key as an argument; and finally, you must define the cryptographic technique that the function should use to sign the JWT.</p>\n<p>To obtain and return the JWT, you'll have to use the echo method above the encode method, as shown below.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;?php</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">// Encode the array to a JWT string.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">echo</span><span class=\"mtk1\"> </span><span class=\"mtk10\">JWT</span><span class=\"mtk1\">::</span><span class=\"mtk11\">encode</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">$request_data</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">$secret_Key</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&#39;HS512&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Now that you have obtained the JWT token, you can transfer it to the client-side and save it using any web programming language of your choice. Let's start with a short JS demonstration of the route ahead.</p>\n<p>First, when a successful form submission takes place, save the created and received JWT in client-side memory. To display some output about the JWT's success, remove the login form and merely display a button that retrieves and displays the JWT's timestamp to the user when it is clicked.</p>\n<p>Here is some sample code for the process mentioned above.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">storeJWT</span><span class=\"mtk1\"> = {}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">loginBtn</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">querySelector</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;#frmLogin&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">btnResource</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">querySelector</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;#btnGetResource&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">formData</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk12\">forms</span><span class=\"mtk1\">[</span><span class=\"mtk7\">0</span><span class=\"mtk1\">]</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// Inserts the jwt to the store object</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">storeJWT</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setJWT</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">data</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">JWT</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">data</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">loginBtn</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addEventListener</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;submit&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk12\">e</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">e</span><span class=\"mtk1\">.</span><span class=\"mtk11\">preventDefault</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">response</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/authenticate.php&quot;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">method:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;POST&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk8\">&quot;Content-type&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;application/x-www-form-urlencoded; charset=UTF-8&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">body:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">formData</span><span class=\"mtk1\">.</span><span class=\"mtk12\">inputEmail</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">formData</span><span class=\"mtk1\">.</span><span class=\"mtk12\">inputPassword</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  })</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> &gt;= </span><span class=\"mtk7\">200</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> &lt;= </span><span class=\"mtk7\">299</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk11\">text</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">storeJWT</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setJWT</span><span class=\"mtk1\">(</span><span class=\"mtk12\">jwt</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">frmLogin</span><span class=\"mtk1\">.</span><span class=\"mtk12\">style</span><span class=\"mtk1\">.</span><span class=\"mtk12\">display</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;none&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">btnResource</span><span class=\"mtk1\">.</span><span class=\"mtk12\">style</span><span class=\"mtk1\">.</span><span class=\"mtk12\">display</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;block&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">// Handle errors</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\">, </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">statusText</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span></code></pre>\n<p>You've already produced and submitted the JWT to the user. So now it's time to put the JWT to use on the user side.</p>\n<h3 id=\"using-jwt\" style=\"position:relative;\"><a href=\"#using-jwt\" aria-label=\"using jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Using JWT</h3>\n<p>As previously stated, if the form submission is successful, you'll display a button to obtain a timestamp. This button will invoke the GET method on the <code>resource.php</code> script. The <code>resource.php</code> script will then set the JWT received after successful authentication in the authentication header.</p>\n<p>The following code will help you achieve this feat.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">btnResource</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addEventListener</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;click&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk12\">e</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/resource.php&quot;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">Authorization:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">`Bearer </span><span class=\"mtk4\">${</span><span class=\"mtk12\">storeJWT</span><span class=\"mtk1\">.</span><span class=\"mtk12\">JWT</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">timeStamp</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\">.</span><span class=\"mtk11\">text</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">timeStamp</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span></code></pre>\n<p>Once you've written this code, run the program and enter your credentials into the form fields. A GET request will be sent when you click the submit button. Here is a sample GET request to assist you in making the correct identification.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">GET /resource.php HTTP/</span><span class=\"mtk7\">1.1</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">Host: yourhost.com</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">Connection: keep-alive</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">Accept: *</span><span class=\"mtk3\">/*</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">X-Requested-With: XMLHttpRequest</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvcWEtYXBpLndlbGx2aWJlLmNvbVwvYXBpXC9hdXRoXC9sb2dpbiIsImlhdCI6MTYzMDQ3OTA5NSwiZXhwIjoxNjMwNDgyNjk1LCJuYmYiOjE2MzA0NzkwOTUsImp0aSI6Imtsa3hHUGpMOVlNTzRSdUsiLCJzdWIiOjc3ODE4LCJwcnYiOiIyM2JkNWM4OTQ5ZjYwMGFkYjM5ZTcwMWM0MDA4NzJkYjdhNTk3NmY3IiwidXNlcnNfaWQiOjc3ODE4LCJtZW1iZXJzX2lkIjo3Nzg4MzMsInByb3h5X3VzZXJfbWVtYmVyc19pZCI6bnVsbH0.TxXwLLu1zWBe7cLLYdFYy3P2HX4AaLgc7WfSRtTgeiI</span></span></code></pre>\n<h3 id=\"validating-jwt\" style=\"position:relative;\"><a href=\"#validating-jwt\" aria-label=\"validating jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Validating JWT</h3>\n<p>If you've followed along until here, everything should be working fine. Now, let's begin with validating the JWT.</p>\n<p>To get help with this operation, you've previously added the composer's autoloader function. You'll now use the <code>preg match</code> function to extract the token from the Bearer header. For this extraction, you'll use the <code>preg match</code> function and supply a regular expression.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> (! </span><span class=\"mtk11\">preg_match</span><span class=\"mtk1\">(</span><span class=\"mtk5\">&#39;/Bearer</span><span class=\"mtk6\">\\s</span><span class=\"mtk5\">(</span><span class=\"mtk6\">\\S</span><span class=\"mtk1\">+</span><span class=\"mtk5\">)/&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">$_SERVER</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&#39;HTTP_AUTHORIZATION&#39;</span><span class=\"mtk1\">], </span><span class=\"mtk12\">$matches</span><span class=\"mtk1\">)) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">header</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;HTTP/1.0 400 Bad Request&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">echo</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;Token not found in request&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">exit</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The code above attempts to extract the token from the Bearer header. In this case, error handling is utilized. Thus if the token is not discovered, an HTTP 404 error is displayed to the user.</p>\n<p>To validate the JWT, you must first compare it to the previously created JWT.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">$jwt</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">$matches</span><span class=\"mtk1\">[</span><span class=\"mtk7\">1</span><span class=\"mtk1\">];</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> (! </span><span class=\"mtk12\">$jwt</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">// No token was able to be extracted from the authorization header</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">header</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;HTTP/1.0 400 Bad Request&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">exit</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The extracted JWT is saved at the first index of the matches array. If the matching array is empty, it means no JWT was extracted. If the preceding code runs successfully, it implies that the JWT has been extracted, and you may now proceed.</p>\n<p>Decoding the received data is required for verifying a JWT. Only the secret key may be used to decode the received data. Once you've obtained the secret key, you may use the static decode function of the PHP-JWT module.</p>\n<p>The decode method requires three arguments, which are as follows.</p>\n<ul>\n<li>The JWT itself</li>\n<li>The secret key</li>\n<li>The algorithm to be used to decode the JWT</li>\n</ul>\n<p>If the decode method succeeds, you may proceed to validate the JWT. The code below will assist you in decoding and validating a JWT.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">$secret_Key</span><span class=\"mtk1\">  = </span><span class=\"mtk8\">&#39;68V0zWFrS72GbpPreidkQFLfj4v9m3Ti+DXc8OB0gcM=&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$token</span><span class=\"mtk1\"> = </span><span class=\"mtk10\">JWT</span><span class=\"mtk1\">::</span><span class=\"mtk11\">decode</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$jwt</span><span class=\"mtk1\">, </span><span class=\"mtk12\">$secret_Key</span><span class=\"mtk1\">, [</span><span class=\"mtk8\">&#39;HS512&#39;</span><span class=\"mtk1\">]);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$now</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">DateTimeImmutable</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$serverName</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;your.domain.name&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">$token</span><span class=\"mtk1\">-&gt;</span><span class=\"mtk12\">iss</span><span class=\"mtk1\"> !== </span><span class=\"mtk12\">$serverName</span><span class=\"mtk1\"> ||</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$token</span><span class=\"mtk1\">-&gt;</span><span class=\"mtk12\">nbf</span><span class=\"mtk1\"> &gt; </span><span class=\"mtk12\">$now</span><span class=\"mtk1\">-&gt;</span><span class=\"mtk11\">getTimestamp</span><span class=\"mtk1\">() ||</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$token</span><span class=\"mtk1\">-&gt;</span><span class=\"mtk12\">exp</span><span class=\"mtk1\"> &lt; </span><span class=\"mtk12\">$now</span><span class=\"mtk1\">-&gt;</span><span class=\"mtk11\">getTimestamp</span><span class=\"mtk1\">())</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">header</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;HTTP/1.1 401 Unauthorized&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">exit</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>This code will provide all the necessary parameters to the decode function and save the method's result. Then, to prevent unauthorized access, error handling is employed. If any of the fields in the JWT are unavailable, an HTTP 401 error indicating unauthorized access will be issued to the user.</p>\n<h2 id=\"loginradius-authentication-for-php-apps\" style=\"position:relative;\"><a href=\"#loginradius-authentication-for-php-apps\" aria-label=\"loginradius authentication for php apps permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>LoginRadius Authentication for PHP Apps</h2>\n<p>Instead of using the process discussed above, you can use <a href=\"https://accounts.loginradius.com/auth.aspx?plan=developer\">LoginRadius Identity Platform</a> to authenticate your PHP APIs quickly. You can start by referring to <a href=\"https://www.loginradius.com/developers/\">LoginRadius PHP documentation</a>.</p>\n<p>In addition, you can use <a href=\"https://www.loginradius.com/developers/\">LoginRadius PHP SDK</a>, which, in turn, simplifies signup and login for your users by eliminating the need for remembering an extra set of credentials for your app.</p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>In this tutorial, you've learned about JWT. Then created a PHP web application and secured it with JWT authentication.</p>\n<p>You understood how easy and important it is to secure a web application.</p>\n<p>You can <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/php\">find the complete code used in this tutorial here</a>.</p>\n<p>Don't forget to try this out for your more significant projects.</p>\n<p>Finally, if you face any problems following this tutorial or have questions, please feel free to comment below. We'll respond as soon as we can to clarify your questions.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk5 { color: #D16969; }\n  .dark-default-dark .mtk6 { color: #D7BA7D; }\n</style>","frontmatter":{"date":"December 24, 2021","updated_date":null,"title":"How to Secure a PHP API Using JWT","tags":["PHP","JWT","Authentication"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/b9e157a812c5801bd8d6ca83f317ee88/58556/jwt.webp","srcSet":"/static/b9e157a812c5801bd8d6ca83f317ee88/61e93/jwt.webp 200w,\n/static/b9e157a812c5801bd8d6ca83f317ee88/1f5c5/jwt.webp 400w,\n/static/b9e157a812c5801bd8d6ca83f317ee88/58556/jwt.webp 800w,\n/static/b9e157a812c5801bd8d6ca83f317ee88/99238/jwt.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Harikrishna Kundariya","github":"espark-biz","avatar":null}}}},{"node":{"fields":{"slug":"/engineering/cookie-based-vs-cookieless-authentication/"},"html":"<p>Securing communications between a client and a server often requires credentials to identify both parties. That is where the different authentication techniques comes in. Two popular authentication methods are cookie-based and cookieless authentication. However, choosing any one of them depends on the organization's requirements. Both come with their benefits and challenges. This article will give a quick walkthrough of cookie-based and cookieless authentication along with their advantages and disadvantages.</p>\n<h2 id=\"what-is-cookie-based-authentication\" style=\"position:relative;\"><a href=\"#what-is-cookie-based-authentication\" aria-label=\"what is cookie based authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is Cookie-based Authentication?</h2>\n<p>Cookies are pieces of data used to identify the user and their preferences. The browser returns the cookie to the server every time the page is requested. Specific cookies like HTTP cookies are used to perform cookie-based authentication to maintain the session for each user.</p>\n<p>The entire cookie-based authentication works in the following manner:</p>\n<ol>\n<li>The user gives a username and password at the time of login. Once the user fills in the login form, the browser (client) sends a login request to the server.</li>\n<li>\n<p>The server verifies the user by querying the user data. If the authentication request is valid, the server generates the following:</p>\n<ul>\n<li>A session by utilizing the user information</li>\n<li>A unique ID, known as the session ID</li>\n</ul>\n<p>The server then passes the session ID to the browser that keeps it. The server also keeps track of the active sessions.</p>\n</li>\n<li>The browser has to submit this generated session ID while sending a subsequent request. Every time the server validates the session ID. The session ID helps the authentication process identify the user and provides access accordingly.</li>\n<li>When the user logs out of the application, the session gets destroyed from both client (browser) and the server. It discontinues the authentication process from happening again through the respective session ID.</li>\n</ol>\n<h3 id=\"benefits-of-cookie-based-authentication\" style=\"position:relative;\"><a href=\"#benefits-of-cookie-based-authentication\" aria-label=\"benefits of cookie based authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Benefits of Cookie-based Authentication</h3>\n<ul>\n<li><strong>Availability:</strong> In cookies-based authentication, cookies can be made available for an extended period, maintaining a session for a long time.</li>\n<li><strong>Easy Configuration:</strong> Websites can deliver cookies by configuring them as per requirement. For example, a website can send cookies that will expire as the users close the browser tab. It is also possible to configure cookies for a specified length of time on the client-side.</li>\n<li><strong>User-friendly:</strong> Cookie-based authentications are simple, and the cookies used in this method are user-friendly. Users can choose what to do with cookie files that have kept user credentials. All modern browsers come with settings to clear the cookies. Users can find cookies in the hard drive and delete them manually.</li>\n</ul>\n<h3 id=\"challenges-of-cookie-based-authentication\" style=\"position:relative;\"><a href=\"#challenges-of-cookie-based-authentication\" aria-label=\"challenges of cookie based authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Challenges of Cookie-based Authentication</h3>\n<ul>\n<li><strong>Vulnerable to CSRF:</strong> Cookie-based authentications are prone to <a href=\"https://www.loginradius.com/blog/engineering/introduction-to-cross-site-request-forgery-csrf/\">Cross-site Request Forgery (CSRF) attacks</a>. Hence, they often require additional security postures for protection.</li>\n<li><strong>Less Mobile-friendly:</strong> Cookie-based authentication does not work well with all native applications.</li>\n<li><strong>Limitations:</strong> There are certain limitations and concerns such as size limit (not more than 4KB of information per cookie), browser limitations on cookies, user privacy, etc., come with cookies and cookie-based authentication.</li>\n<li><strong>Less Scalable:</strong> Cookie-based authentication is less scalable, and the overhead rises when the user count increases on a particular site.</li>\n</ul>\n<h2 id=\"what-is-cookieless-authentication\" style=\"position:relative;\"><a href=\"#what-is-cookieless-authentication\" aria-label=\"what is cookieless authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is Cookieless Authentication?</h2>\n<p>Cookieless authentication, also known as token-based authentication, is a technique that leverages JSON web tokens (JWT) instead of cookies to authenticate a user. It uses a protocol that creates encrypted security tokens. These tokens allow the user to verify their identity. In return, the users receive a unique access token to perform the authentication. The token contains information about user identities and transmits it securely between the server and client.\nThe entire cookieless authentication works in the following manner:</p>\n<ol>\n<li>The user logs into the service by providing their login credentials. It issues an access request from the client-side by sending the credential and API key (public key) to the application server.</li>\n<li>The server verifies the login credentials that checks the password entered against the username. Once approved, the server will generate a unique session token that will help authorize subsequent actions.</li>\n<li>This access token is sent back to the client via URL query strings, post request body, or other means. The server-generated signed authentication token gets assigned with an expiration time.</li>\n<li>The token gets transmitted back to the user's browser. On every subsequent request to the application server or future website visits, the access token gets added to the authorization header along with the public key. If there is a match from the application server against the private key, the user can proceed. If a given token expires, a new token gets generated as an authentication request.</li>\n</ol>\n<h3 id=\"benefits-of-cookieless-authentication\" style=\"position:relative;\"><a href=\"#benefits-of-cookieless-authentication\" aria-label=\"benefits of cookieless authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Benefits of Cookieless Authentication</h3>\n<ul>\n<li><strong>Scalable and Efficient:</strong> In cookieless authentication, the tokens remain stored on the user's end. The server only needs to sign the authentication token once on successful login. That makes the entire technique scalable and allows maintaining more users on an application at once without any hassle.</li>\n<li><strong>Better Performance:</strong> Cookie-based authentication requires the server to perform an authentication lookup every time the user requests a page. You can eliminate the round-trips with tokens through the cookieless authentication technique. In cookieless authentication, the access token and the public key are added to the authorization header on every page request.</li>\n<li><strong>Robust Security:</strong> Since cookieless authentication leverages tokens like JWT (stateless), only a private key (used to create the authentication token) can validate it when received at the server-side.</li>\n<li><strong>Seamless Across Devices:</strong> Cookieless authentication works well with all native applications. Tokens are much easier to implement on iOS, Android, IoT devices, and distributed systems, making the authentication system seamless.</li>\n<li><strong>Expiration Time:</strong> Usually, tokens get generated with an expiration time, after which they become invalid. Then a new token needs to be obtained for reauthentication. If a token gets leaked, the potential damage becomes much smaller due to its short lifespan.</li>\n</ul>\n<h3 id=\"challenges-with-cookieless-authentication\" style=\"position:relative;\"><a href=\"#challenges-with-cookieless-authentication\" aria-label=\"challenges with cookieless authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Challenges with Cookieless Authentication</h3>\n<ul>\n<li><strong>Single-key Token:</strong> One of the significant challenges with cookieless authentication is that these access tokens rely on just one key. Tokens that use JWT leverages a single key for authentication. If the developers/administrators handle the key poorly, it can lead to severe consequences that can compromise sensitive information.</li>\n<li><strong>Data Overhead:</strong> Storing a lot of data increases the overall size of the token. It slows down the request impacting the overall loading speed. This slowing down ultimately hampers the user experience. Thus proper development practices need to be followed, regulating minimum but essential data into the token.</li>\n<li><strong>Vulnerable to XSS and CSRF:</strong> Cookieless authentications are susceptible to <a href=\"https://www.loginradius.com/blog/engineering/http-security-headers/\">XSS</a> and CSRF attacks. So, the best practice is to have a short expiration time for access tokens. Keeping a longer expiration time might allow the attackers to hijack the access token and use it to gain unauthorized authentication.</li>\n</ul>\n<h2 id=\"how-does-loginradius-have-native-support-for-cookieless-authentication\" style=\"position:relative;\"><a href=\"#how-does-loginradius-have-native-support-for-cookieless-authentication\" aria-label=\"how does loginradius have native support for cookieless authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How does LoginRadius have Native Support for Cookieless Authentication?</h2>\n<p>LoginRadius provides multiple methods to implement a cookieless login workflow leveraging industry and security best practices. As a consumer-centric Identity platform, LoginRadius ensures that modern implementation methodologies comply with the changing security landscape. The cookieless authentication workflows detailed below are systems that LoginRadius has developed support for even before the recent browser-based privacy policies and are a core part of the LoginRadius platform.</p>\n<h3 id=\"loginradius-apis\" style=\"position:relative;\"><a href=\"#loginradius-apis\" aria-label=\"loginradius apis permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>LoginRadius APIs</h3>\n<p>The LoginRadius API has been architected and designed to function as a cookieless authentication system. Once authentication occurs, a session token gets returned to the requesting client in the form of an access token which can be leveraged to take further authorized actions against the Consumer account. It is a core part of the LoginRadius authentication workflows, and APIs developed based on Oauth 2.0 protocols.</p>\n<p>These APIs provide flexibility in generating access tokens based on consumer authentication requests and are automatically validated and signed leveraging the LoginRadius API Key and Secret. <a href=\"https://www.loginradius.com/developers/\">Detailed API documentation is available here</a>.</p>\n<h3 id=\"json-web-tokens\" style=\"position:relative;\"><a href=\"#json-web-tokens\" aria-label=\"json web 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>JSON Web Tokens</h3>\n<p>In addition to the LoginRadius APIs, JWTs are a standard method to handle cookieless login. Once authentication is completed and verified, a signed token can be generated(leveraging LoginRadius APIs) to pass the consumer session to the client.</p>\n<p>JWTs are a standard industry mechanism leveraged by various service providers and tools, making them ideal for interoperability with multiple applications. Find additional details on <a href=\"https://www.loginradius.com/developers/\">how to use JWT as part of your authentication workflows here</a>.</p>\n<h3 id=\"additional-options\" style=\"position:relative;\"><a href=\"#additional-options\" aria-label=\"additional options permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Additional Options</h3>\n<p>In addition to the above two options, LoginRadius provides flexibility and support for various authentication and authorization standards that support a cookieless authentication approach. Outbound authentication workflows such as OIDC and Oauth 2.0 allow for a modern standardized approach to authentication.</p>\n<p>These are industry-recognized and recommended authentication and authorization protocols that comply with security and privacy best practices, including supporting a cookieless authentication approach. Check out <a href=\"https://www.loginradius.com/developers/\">our dedicated documentation on outbound workflows</a>.</p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>Cookieless authentication can facilitate more secure and scalable authentication. You should decide how to authenticate consumers considering your requirements and the benefits and challenges of cookie-based and cookieless authentication.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"December 14, 2021","updated_date":null,"title":"Cookie-based vs. Cookieless Authentication: What’s the Future?","tags":["Authentication","JWT","Cookie"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/0be9d40cc7bb77e9feb433ff59d7514a/58556/coverImage.webp","srcSet":"/static/0be9d40cc7bb77e9feb433ff59d7514a/61e93/coverImage.webp 200w,\n/static/0be9d40cc7bb77e9feb433ff59d7514a/1f5c5/coverImage.webp 400w,\n/static/0be9d40cc7bb77e9feb433ff59d7514a/58556/coverImage.webp 800w,\n/static/0be9d40cc7bb77e9feb433ff59d7514a/99238/coverImage.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Kundan Singh","github":null,"avatar":null}}}},{"node":{"fields":{"slug":"/engineering/guest-post/securing-flask-api-with-jwt/"},"html":"<p>Authentication is an essential part of any web application. But unfortunately, it is not always easy to implement.</p>\n<h2 id=\"what-is-authentication\" style=\"position:relative;\"><a href=\"#what-is-authentication\" aria-label=\"what is authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is Authentication?</h2>\n<p>Authentication is a process of verifying that an entity is who they claim to be. For example, a user might authenticate by providing a username and password. If the username and password are valid, the system will check if the user can access the resource. After the system checks the user's details against its database and if the details are valid, the user is thus authenticated and can access available resources.</p>\n<h2 id=\"authentication-factors\" style=\"position:relative;\"><a href=\"#authentication-factors\" aria-label=\"authentication factors permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Factors</h2>\n<p>The following factors are used to authenticate a user.</p>\n<h3 id=\"single-factor-authentication\" style=\"position:relative;\"><a href=\"#single-factor-authentication\" aria-label=\"single factor authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Single-factor Authentication</h3>\n<p>This authentication is used when a user provides a username/email/phone number and a password. This is the most common and weakest authentication factor. The user simply inputs the email and password, and the system checks if the data is valid; if valid, the user gets authenticated and can access the resource. What happens if another person who is not a legitimate user tries to access the resource? The system denies access to the resource.</p>\n<h3 id=\"multi-factor-authentication\" style=\"position:relative;\"><a href=\"#multi-factor-authentication\" aria-label=\"multi factor authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><a href=\"https://www.loginradius.com/multi-factor-authentication/\">Multi-factor Authentication</a></h3>\n<p>This authentication uses more than one factor to authenticate a user. For example, the user tries to log in with, say, email and password; if the data is correct, a code is sent to the user's phone number, and the user is asked to input the code. If the user enters the code, the user gets logged in; otherwise, the user is not authenticated. Some applications even go a step further by not using two factors but using three factors.</p>\n<h2 id=\"types-of-authentication\" style=\"position:relative;\"><a href=\"#types-of-authentication\" aria-label=\"types of authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Types of Authentication</h2>\n<p>There are three types of authentication, as follows:</p>\n<ol>\n<li><strong>Knowledge Authentication</strong>: The user is asked something that only they can provide or know -- e.g., password. This is the most common type and also the easiest.</li>\n<li><strong>Property Authentication</strong>: The user is asked for something they own or possess. For example, they can use a hardware authentication device like YubiKey or an authenticator app on their phone. The idea is that users will be asked to set an authentication factor that verifies the identity more securely. This isn’t always used alone; it’s used alongside another authentication type, say, <code>Knowledge authentication</code>.</li>\n<li><strong>Biological Authentication</strong>: The user is asked to verify their identity using something biologically unique to them -- e.g., a fingerprint or iris scan.</li>\n</ol>\n<p>In most applications, knowledge and property authentication are used as an extra layer of authentication.</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>The following are the differences between authentication and authorization:</p>\n<ol>\n<li>Authentication verifies identity (usually through credential validation)) while authorization grants or denies permissions to a user.</li>\n<li>Authentication is used to verify that users are who they say they are. Authorization is used to verify that a user has permission to do something.</li>\n</ol>\n<h2 id=\"starter-application\" style=\"position:relative;\"><a href=\"#starter-application\" aria-label=\"starter application permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Starter Application</h2>\n<p>In this tutorial, you'll work on authentication in flask middleware for an existing API built with <a href=\"https://flask.palletsprojects.com/en/2.0.x/\">Flask</a> and <a href=\"https://pymongo.readthedocs.io/en/stable/\">PyMongo</a>. The API is a book library API using which users can create books and upload cover images for the books and relevant data. PyMongo is used to connect to the mongo database. You'll use the PyJWT library to generate and verify JWT tokens for auth in flask.  </p>\n<blockquote>\n<p>You can learn <a href=\"https://www.loginradius.com/blog/engineering/guest-post/jwt-authentication-best-practices-and-when-to-use/\">more about JSON Web Tokens (JWT) here</a>.</p>\n</blockquote>\n<p>To get started, clone the repository and set up the application by running the following commands:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">git clone https://github.com/LoginRadius/engineering-blog-samples.git </span><span class=\"mtk3\"># Clone the repository</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">cd</span><span class=\"mtk1\"> /Flask/loginRadius-flask-auth </span><span class=\"mtk3\"># change directory</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">python3 -m venv env </span><span class=\"mtk3\"># create virtual environment; if you&#39;re using Windows, `py -m venv env`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">source</span><span class=\"mtk1\"> env/bin/activate </span><span class=\"mtk3\"># activate virtual environment, if you&#39;re using windows, env/Scripts/activate</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">pip install -r requirements.txt </span><span class=\"mtk3\"># install dependencies</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"># https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/</span></span></code></pre>\n<p>The application is now set up and ready to run. You can run the app using the command <code>flask run</code> in the project directory. You can test that all the endpoints are working by testing the app in an API testing tool, like Postman.</p>\n<h2 id=\"authentication-middleware\" style=\"position:relative;\"><a href=\"#authentication-middleware\" aria-label=\"authentication middleware permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Middleware</h2>\n<p>As you've noticed, anybody can access the API; you need to restrict access to the API. Create new book data if they have the correct data, then add, delete, and update book data, but you don't want that. To do this, you need to implement an authentication middleware.</p>\n<p>When we talk about authentication with flask, middlewares are created in Flask by creating a decorator; a function can have multiple middlewares, and the order matters a lot. </p>\n<p>To create your auth middleware, you need to install PyJWT -- the library you'll use to generate tokens. You’ll also use Pillow to alter image data before saving them to disk. Run the following command to install the packages:</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\">pip install pyjwt pillow</span></span></code></pre>\n<p>You need to add a secret key to your application; this is what you should pass to JWT.</p>\n<p>Add the following to your <code>app.py</code> file below the app declaration.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"python\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\"># app = Flask(__name__)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">SECRET_KEY = os.environ.get(</span><span class=\"mtk8\">&#39;SECRET_KEY&#39;</span><span class=\"mtk1\">) </span><span class=\"mtk4\">or</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;this is a secret&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">print</span><span class=\"mtk1\">(SECRET_KEY)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">app.config[</span><span class=\"mtk8\">&#39;SECRET_KEY&#39;</span><span class=\"mtk1\">] = SECRET_KEY</span></span></code></pre>\n<p>Let's create a file called <code>auth_middleware.py</code> in the root of your application and place the following inside this file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"python\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">from</span><span class=\"mtk1\"> functools </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> wraps</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> jwt</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">from</span><span class=\"mtk1\"> flask </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> request, abort</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">from</span><span class=\"mtk1\"> flask </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> current_app</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> models</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">token_required</span><span class=\"mtk1\">(</span><span class=\"mtk12\">f</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">@wraps</span><span class=\"mtk1\">(f)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">decorated</span><span class=\"mtk1\">(*</span><span class=\"mtk12\">args</span><span class=\"mtk1\">, **</span><span class=\"mtk12\">kwargs</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        token = </span><span class=\"mtk4\">None</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Authorization&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk4\">in</span><span class=\"mtk1\"> request.headers:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            token = request.headers[</span><span class=\"mtk8\">&quot;Authorization&quot;</span><span class=\"mtk1\">].split(</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\">if</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> token:</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=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Authentication Token is missing!&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Unauthorized&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }, </span><span class=\"mtk7\">401</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\">            data=jwt.decode(token, current_app.config[</span><span class=\"mtk8\">&quot;SECRET_KEY&quot;</span><span class=\"mtk1\">], </span><span class=\"mtk12\">algorithms</span><span class=\"mtk1\">=[</span><span class=\"mtk8\">&quot;HS256&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            current_user=models.User().get_by_id(data[</span><span class=\"mtk8\">&quot;user_id&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> current_user </span><span class=\"mtk4\">is</span><span class=\"mtk1\"> </span><span class=\"mtk4\">None</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=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Invalid Authentication token!&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Unauthorized&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }, </span><span class=\"mtk7\">401</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> current_user[</span><span class=\"mtk8\">&quot;active&quot;</span><span class=\"mtk1\">]:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                abort(</span><span class=\"mtk7\">403</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">except</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Exception</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> e:</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=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Something went wrong&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(e)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }, </span><span class=\"mtk7\">500</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> f(current_user, *args, **kwargs)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> decorated</span></span></code></pre>\n<p>The function above is simply a decorator function. Inside this function, you check if there is an <code>Authorization</code> field in the headers part of the request; if this is missing, you return an authorization error.</p>\n<p>Next, you check if it exists but is not valid; if it is not valid, you also return an authorization error.</p>\n<p>If everything goes fine, then the view function is called. As you can see, you return <code>f(current_user, *args, **kwargs)</code>, where <code>f</code> is the next decorator or function that's being called after this decorator -- in your case, the view function, which means that the first argument of any view function that uses this decorator must be <code>current_user</code>.</p>\n<h2 id=\"auth-routes\" style=\"position:relative;\"><a href=\"#auth-routes\" aria-label=\"auth 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>Auth Routes</h2>\n<p>You currently have a route to creating a new user, but you don't have one to log in. From what you have above, you're checking if the token passed as the header is valid, but now the question is -- how do you get to know the token. Basically, the login route fetches the token and sends it to the client.</p>\n<p>Add the following function below the <code>add_user</code> function:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"python\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/users/login&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">methods</span><span class=\"mtk1\">=[</span><span class=\"mtk8\">&quot;POST&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">login</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\">        data = request.json</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> data:</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=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Please provide user details&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Bad request&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }, </span><span class=\"mtk7\">400</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk3\"># validate input</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        is_validated = validate_email_and_password(data.get(</span><span class=\"mtk8\">&#39;email&#39;</span><span class=\"mtk1\">), data.get(</span><span class=\"mtk8\">&#39;password&#39;</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> is_validated </span><span class=\"mtk4\">is</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</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\">return</span><span class=\"mtk1\"> </span><span class=\"mtk10\">dict</span><span class=\"mtk1\">(</span><span class=\"mtk12\">message</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&#39;Invalid data&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">data</span><span class=\"mtk1\">=</span><span class=\"mtk4\">None</span><span class=\"mtk1\">, </span><span class=\"mtk12\">error</span><span class=\"mtk1\">=is_validated), </span><span class=\"mtk7\">400</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        user = User().login(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            data[</span><span class=\"mtk8\">&quot;email&quot;</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            data[</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\">]</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> user:</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\"># token should expire after 24 hrs</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                user[</span><span class=\"mtk8\">&quot;token&quot;</span><span class=\"mtk1\">] = jwt.encode(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    {</span><span class=\"mtk8\">&quot;user_id&quot;</span><span class=\"mtk1\">: user[</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">]},</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    app.config[</span><span class=\"mtk8\">&quot;SECRET_KEY&quot;</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">algorithm</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;HS256&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\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Successfully fetched auth token&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: user</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">except</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Exception</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> e:</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=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Something went wrong&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(e)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }, </span><span class=\"mtk7\">500</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=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Error fetching auth token!, invalid email or password&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Unauthorized&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }, </span><span class=\"mtk7\">404</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">except</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Exception</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> e:</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=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Something went wrong!&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(e),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }, </span><span class=\"mtk7\">500</span></span></code></pre>\n<h2 id=\"protecting-api-routes-in-flask\" style=\"position:relative;\"><a href=\"#protecting-api-routes-in-flask\" aria-label=\"protecting api routes in flask permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Protecting API Routes in Flask</h2>\n<p>So far, you've been able to create your auth middleware, but you need to use this middleware to protect routes. All you need to do is to pass this middleware immediately after the <code>app.route</code> middleware, then make <code>current_user</code> the first argument of the view function, as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"python\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@token_required</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">user</span><span class=\"mtk1\">(</span><span class=\"mtk12\">current_user</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> jsonify(current_user)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/&lt;pdt_id&gt;&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@token_required</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">product</span><span class=\"mtk1\">(</span><span class=\"mtk12\">current_user</span><span class=\"mtk1\">, </span><span class=\"mtk12\">pdt_id</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> jsonify(Product.find({</span><span class=\"mtk8\">&#39;user_id&#39;</span><span class=\"mtk1\">: pdt_id}))</span></span></code></pre>\n<p>Add this middleware (<code>@token_required</code>) to every function you only want authenticated users to access. In the end, your whole <code>app.py</code> file should look as follows.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"python\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> jwt, os</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">from</span><span class=\"mtk1\"> dotenv </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> load_dotenv</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">from</span><span class=\"mtk1\"> flask </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> Flask, request, jsonify</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">from</span><span class=\"mtk1\"> save_image </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> save_pic</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">from</span><span class=\"mtk1\"> validate </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> validate_book, validate_email_and_password, validate_user</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">load_dotenv()</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">app = Flask(</span><span class=\"mtk12\">__name__</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">SECRET_KEY = os.environ.get(</span><span class=\"mtk8\">&#39;SECRET_KEY&#39;</span><span class=\"mtk1\">) </span><span class=\"mtk4\">or</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;this is a secret&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">print</span><span class=\"mtk1\">(SECRET_KEY)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">app.config[</span><span class=\"mtk8\">&#39;SECRET_KEY&#39;</span><span class=\"mtk1\">] = SECRET_KEY</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">from</span><span class=\"mtk1\"> models </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> Books, User</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">from</span><span class=\"mtk1\"> auth_middleware </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> token_required</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">hello</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;Hello World!&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/users/&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">methods</span><span class=\"mtk1\">=[</span><span class=\"mtk8\">&quot;POST&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">add_user</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\">        user = request.json</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> user:</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=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Please provide user details&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Bad request&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }, </span><span class=\"mtk7\">400</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        is_validated = validate_user(**user)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> is_validated </span><span class=\"mtk4\">is</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</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\">return</span><span class=\"mtk1\"> </span><span class=\"mtk10\">dict</span><span class=\"mtk1\">(</span><span class=\"mtk12\">message</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&#39;Invalid data&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">data</span><span class=\"mtk1\">=</span><span class=\"mtk4\">None</span><span class=\"mtk1\">, </span><span class=\"mtk12\">error</span><span class=\"mtk1\">=is_validated), </span><span class=\"mtk7\">400</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        user = User().create(**user)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> user:</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=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;User already exists&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Conflict&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }, </span><span class=\"mtk7\">409</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=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Successfully created new user&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: user</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }, </span><span class=\"mtk7\">201</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">except</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Exception</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> e:</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=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Something went wrong&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(e),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }, </span><span class=\"mtk7\">500</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/users/login&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">methods</span><span class=\"mtk1\">=[</span><span class=\"mtk8\">&quot;POST&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">login</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\">        data = request.json</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> data:</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=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Please provide user details&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Bad request&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }, </span><span class=\"mtk7\">400</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk3\"># validate input</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        is_validated = validate_email_and_password(data.get(</span><span class=\"mtk8\">&#39;email&#39;</span><span class=\"mtk1\">), data.get(</span><span class=\"mtk8\">&#39;password&#39;</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> is_validated </span><span class=\"mtk4\">is</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</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\">return</span><span class=\"mtk1\"> </span><span class=\"mtk10\">dict</span><span class=\"mtk1\">(</span><span class=\"mtk12\">message</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&#39;Invalid data&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">data</span><span class=\"mtk1\">=</span><span class=\"mtk4\">None</span><span class=\"mtk1\">, </span><span class=\"mtk12\">error</span><span class=\"mtk1\">=is_validated), </span><span class=\"mtk7\">400</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        user = User().login(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            data[</span><span class=\"mtk8\">&quot;email&quot;</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            data[</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\">]</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> user:</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\"># token should expire after 24 hrs</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                user[</span><span class=\"mtk8\">&quot;token&quot;</span><span class=\"mtk1\">] = jwt.encode(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    {</span><span class=\"mtk8\">&quot;user_id&quot;</span><span class=\"mtk1\">: user[</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">]},</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    app.config[</span><span class=\"mtk8\">&quot;SECRET_KEY&quot;</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">algorithm</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;HS256&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\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Successfully fetched auth token&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: user</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">except</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Exception</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> e:</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=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Something went wrong&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(e)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }, </span><span class=\"mtk7\">500</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=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Error fetching auth token!, invalid email or password&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Unauthorized&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }, </span><span class=\"mtk7\">404</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">except</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Exception</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> e:</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=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Something went wrong!&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(e),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }, </span><span class=\"mtk7\">500</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/users/&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">methods</span><span class=\"mtk1\">=[</span><span class=\"mtk8\">&quot;GET&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@token_required</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">get_current_user</span><span class=\"mtk1\">(</span><span class=\"mtk12\">current_user</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> jsonify({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;successfully retrieved user profile&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: current_user</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=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/users/&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">methods</span><span class=\"mtk1\">=[</span><span class=\"mtk8\">&quot;PUT&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@token_required</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">update_user</span><span class=\"mtk1\">(</span><span class=\"mtk12\">current_user</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\">        user = request.json</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> user.get(</span><span class=\"mtk8\">&quot;name&quot;</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            user = User().update(current_user[</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">], user[</span><span class=\"mtk8\">&quot;name&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> jsonify({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;successfully updated account&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: user</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }), </span><span class=\"mtk7\">201</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=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Invalid data, you can only update your account name!&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Bad Request&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }, </span><span class=\"mtk7\">400</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">except</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Exception</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> e:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> jsonify({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;failed to update account&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(e),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }), </span><span class=\"mtk7\">400</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/users/&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">methods</span><span class=\"mtk1\">=[</span><span class=\"mtk8\">&quot;DELETE&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@token_required</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">disable_user</span><span class=\"mtk1\">(</span><span class=\"mtk12\">current_user</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\">        User().disable_account(current_user[</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> jsonify({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;successfully disabled acount&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }), </span><span class=\"mtk7\">204</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">except</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Exception</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> e:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> jsonify({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;failed to disable account&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(e),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }), </span><span class=\"mtk7\">400</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/books/&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">methods</span><span class=\"mtk1\">=[</span><span class=\"mtk8\">&quot;POST&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@token_required</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">add_book</span><span class=\"mtk1\">(</span><span class=\"mtk12\">current_user</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\">        book = </span><span class=\"mtk10\">dict</span><span class=\"mtk1\">(request.form)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> book:</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=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Invalid data, you need to give the book title, cover image, author id,&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Bad Request&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }, </span><span class=\"mtk7\">400</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> request.files[</span><span class=\"mtk8\">&quot;cover_image&quot;</span><span class=\"mtk1\">]:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;cover image is required&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }, </span><span class=\"mtk7\">400</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        book[</span><span class=\"mtk8\">&quot;image_url&quot;</span><span class=\"mtk1\">] = request.host_url+</span><span class=\"mtk8\">&quot;static/books/&quot;</span><span class=\"mtk1\">+save_pic(request.files[</span><span class=\"mtk8\">&quot;cover_image&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        book[</span><span class=\"mtk8\">&quot;user_id&quot;</span><span class=\"mtk1\">] = current_user[</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">]</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        is_validated = validate_book(**book)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> is_validated </span><span class=\"mtk4\">is</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</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\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Invalid data&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: is_validated</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }, </span><span class=\"mtk7\">400</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        book = Books().create(**book)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> book:</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=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;The book has been created by user&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Conflict&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }, </span><span class=\"mtk7\">400</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> jsonify({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;successfully created a new book&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: book</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }), </span><span class=\"mtk7\">201</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">except</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Exception</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> e:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> jsonify({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;failed to create a new book&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(e),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }), </span><span class=\"mtk7\">500</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/books/&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">methods</span><span class=\"mtk1\">=[</span><span class=\"mtk8\">&quot;GET&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@token_required</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">get_books</span><span class=\"mtk1\">(</span><span class=\"mtk12\">current_user</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\">        books = Books().get_by_user_id(current_user[</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> jsonify({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;successfully retrieved all books&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: books</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">except</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Exception</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> e:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> jsonify({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;failed to retrieve all books&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(e),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }), </span><span class=\"mtk7\">500</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/books/&lt;book_id&gt;&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">methods</span><span class=\"mtk1\">=[</span><span class=\"mtk8\">&quot;GET&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@token_required</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">get_book</span><span class=\"mtk1\">(</span><span class=\"mtk12\">current_user</span><span class=\"mtk1\">, </span><span class=\"mtk12\">book_id</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\">        book = Books().get_by_id(book_id)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> book:</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=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Book not found&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Not Found&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }, </span><span class=\"mtk7\">404</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> jsonify({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;successfully retrieved a book&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: book</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">except</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Exception</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> e:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> jsonify({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Something went wrong&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(e),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }), </span><span class=\"mtk7\">500</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/books/&lt;book_id&gt;&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">methods</span><span class=\"mtk1\">=[</span><span class=\"mtk8\">&quot;PUT&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@token_required</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">update_book</span><span class=\"mtk1\">(</span><span class=\"mtk12\">current_user</span><span class=\"mtk1\">, </span><span class=\"mtk12\">book_id</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\">        book = Books().get_by_id(book_id)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> book </span><span class=\"mtk4\">or</span><span class=\"mtk1\"> book[</span><span class=\"mtk8\">&quot;user_id&quot;</span><span class=\"mtk1\">] != current_user[</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">]:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Book not found for user&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Not found&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }, </span><span class=\"mtk7\">404</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        book = request.form</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> book.get(</span><span class=\"mtk8\">&#39;cover_image&#39;</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            book[</span><span class=\"mtk8\">&quot;image_url&quot;</span><span class=\"mtk1\">] = request.host_url+</span><span class=\"mtk8\">&quot;static/books/&quot;</span><span class=\"mtk1\">+save_pic(request.files[</span><span class=\"mtk8\">&quot;cover_image&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        book = Books().update(book_id, **book)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> jsonify({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;successfully updated a book&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: book</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }), </span><span class=\"mtk7\">201</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">except</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Exception</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> e:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> jsonify({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;failed to update a book&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(e),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }), </span><span class=\"mtk7\">400</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/books/&lt;book_id&gt;&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">methods</span><span class=\"mtk1\">=[</span><span class=\"mtk8\">&quot;DELETE&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@token_required</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">delete_book</span><span class=\"mtk1\">(</span><span class=\"mtk12\">current_user</span><span class=\"mtk1\">, </span><span class=\"mtk12\">book_id</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\">        book = Books().get_by_id(book_id)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> book </span><span class=\"mtk4\">or</span><span class=\"mtk1\"> book[</span><span class=\"mtk8\">&quot;user_id&quot;</span><span class=\"mtk1\">] != current_user[</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">]:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Book not found for user&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Not found&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }, </span><span class=\"mtk7\">404</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        Books().delete(book_id)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> jsonify({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;successfully deleted a book&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }), </span><span class=\"mtk7\">204</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">except</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Exception</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> e:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> jsonify({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;failed to delete a book&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(e),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }), </span><span class=\"mtk7\">400</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@app.errorhandler</span><span class=\"mtk1\">(</span><span class=\"mtk7\">403</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">forbidden</span><span class=\"mtk1\">(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> jsonify({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Forbidden&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(e),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }), </span><span class=\"mtk7\">403</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@app.errorhandler</span><span class=\"mtk1\">(</span><span class=\"mtk7\">404</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">forbidden</span><span class=\"mtk1\">(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> jsonify({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&quot;message&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Endpoint Not Found&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(e),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&quot;data&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">None</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }), </span><span class=\"mtk7\">404</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk12\">__name__</span><span class=\"mtk1\"> == </span><span class=\"mtk8\">&quot;__main__&quot;</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    app.run(</span><span class=\"mtk12\">debug</span><span class=\"mtk1\">=</span><span class=\"mtk4\">True</span><span class=\"mtk1\">)</span></span></code></pre>\n<p>Before running the application, let's look at the <code>save_pic</code> function inside the <code>save_image.py</code> file. This is the function responsible for saving uploaded pictures.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"python\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">from</span><span class=\"mtk1\"> PIL </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> Image</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> secrets, os</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">from</span><span class=\"mtk1\"> flask </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> current_app </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> app</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">save_pic</span><span class=\"mtk1\">(</span><span class=\"mtk12\">picture</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    file_name = secrets.token_hex(</span><span class=\"mtk7\">8</span><span class=\"mtk1\">) +os.path.splitext(picture.filename)[</span><span class=\"mtk7\">1</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=\"mtk4\">not</span><span class=\"mtk1\"> os.path.isdir(os.path.join(app.root_path, </span><span class=\"mtk8\">&#39;static&#39;</span><span class=\"mtk1\">)):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        os.mkdir(os.path.join(app.root_path,</span><span class=\"mtk8\">&quot;static&quot;</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        os.mkdir(os.path.join(app.root_path,</span><span class=\"mtk8\">&quot;static/images&quot;</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        os.mkdir(os.path.join(app.root_path,</span><span class=\"mtk8\">&quot;static/images/books&quot;</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=\"mtk4\">not</span><span class=\"mtk1\"> os.path.isdir(os.path.join(app.root_path, </span><span class=\"mtk8\">&#39;static/images&#39;</span><span class=\"mtk1\">)):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        os.mkdir(os.path.join(app.root_path,</span><span class=\"mtk8\">&quot;static/images&quot;</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        os.mkdir(os.path.join(app.root_path,</span><span class=\"mtk8\">&quot;static/images/books&quot;</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=\"mtk4\">not</span><span class=\"mtk1\"> os.path.isdir(os.path.join(app.root_path, </span><span class=\"mtk8\">&#39;static/images/books&#39;</span><span class=\"mtk1\">)):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        os.mkdir(os.path.join(app.root_path,</span><span class=\"mtk8\">&quot;static/images/books&quot;</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    file_path = os.path.join(app.root_path, </span><span class=\"mtk8\">&quot;static/images/books&quot;</span><span class=\"mtk1\">, file_name)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    picture = Image.open(picture)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    picture.thumbnail((</span><span class=\"mtk7\">150</span><span class=\"mtk1\">, </span><span class=\"mtk7\">150</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    picture.save(file_path)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> file_name</span></span></code></pre>\n<p>You should also add the following functions as helper methods of the <code>User</code> model class.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"python\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">disable_account</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user_id</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    user = db.users.update_one(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        {</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">: bson.ObjectId(user_id)},</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        {</span><span class=\"mtk8\">&quot;$set&quot;</span><span class=\"mtk1\">: {</span><span class=\"mtk8\">&quot;active&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">False</span><span class=\"mtk1\">}}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    user = </span><span class=\"mtk4\">self</span><span class=\"mtk1\">.get_by_id(user_id)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> user</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">encrypt_password</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> generate_password_hash(password)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">login</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</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=\"mtk8\">&quot;&quot;&quot;Login a user&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    user = </span><span class=\"mtk4\">self</span><span class=\"mtk1\">.get_by_email(email)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> user </span><span class=\"mtk4\">or</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> check_password_hash(user[</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\">], password):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    user.pop(</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> user</span></span></code></pre>\n<p>Your <code>models.py</code> file should look as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"python\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk8\">&quot;&quot;&quot;Application Models&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> bson, os</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">from</span><span class=\"mtk1\"> dotenv </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> load_dotenv</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">from</span><span class=\"mtk1\"> pymongo </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> MongoClient</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">from</span><span class=\"mtk1\"> werkzeug.security </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> generate_password_hash, check_password_hash</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">load_dotenv()</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">DATABASE_URL=os.environ.get(</span><span class=\"mtk8\">&#39;DATABASE_URL&#39;</span><span class=\"mtk1\">) </span><span class=\"mtk4\">or</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;mongodb://localhost:27017/myDatabase&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">print</span><span class=\"mtk1\">(DATABASE_URL)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">client = MongoClient(DATABASE_URL)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">db = client.myDatabase</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Books</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&quot;&quot;&quot;Books Model&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">__init__</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">create</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">, </span><span class=\"mtk12\">title</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">description</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">image_url</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">category</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user_id</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=\"mtk8\">&quot;&quot;&quot;Create a new book&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        book = </span><span class=\"mtk4\">self</span><span class=\"mtk1\">.get_by_user_id_and_title(user_id, title)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> book:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        new_book = db.books.insert_one(</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;title&quot;</span><span class=\"mtk1\">: title,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;description&quot;</span><span class=\"mtk1\">: description,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;image_url&quot;</span><span class=\"mtk1\">: image_url,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;category&quot;</span><span class=\"mtk1\">: category,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;user_id&quot;</span><span class=\"mtk1\">: user_id</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">self</span><span class=\"mtk1\">.get_by_id(new_book.inserted_id)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">get_all</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&quot;&quot;&quot;Get all books&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        books = db.books.find()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> [{**book, </span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(book[</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">])} </span><span class=\"mtk15\">for</span><span class=\"mtk1\"> book </span><span class=\"mtk4\">in</span><span class=\"mtk1\"> books]</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">get_by_id</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">, </span><span class=\"mtk12\">book_id</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&quot;&quot;&quot;Get a book by id&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        book = db.books.find_one({</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">: bson.ObjectId(book_id)})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> book:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        book[</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">] = </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(book[</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> book</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">get_by_user_id</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user_id</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&quot;&quot;&quot;Get all books created by a user&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        books = db.books.find({</span><span class=\"mtk8\">&quot;user_id&quot;</span><span class=\"mtk1\">: user_id})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> [{**book, </span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(book[</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">])} </span><span class=\"mtk15\">for</span><span class=\"mtk1\"> book </span><span class=\"mtk4\">in</span><span class=\"mtk1\"> books]</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">get_by_category</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">, </span><span class=\"mtk12\">category</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&quot;&quot;&quot;Get all books by category&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        books = db.books.find({</span><span class=\"mtk8\">&quot;category&quot;</span><span class=\"mtk1\">: category})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> [book </span><span class=\"mtk15\">for</span><span class=\"mtk1\"> book </span><span class=\"mtk4\">in</span><span class=\"mtk1\"> books]</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">get_by_user_id_and_category</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user_id</span><span class=\"mtk1\">, </span><span class=\"mtk12\">category</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&quot;&quot;&quot;Get all books by category for a particular user&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        books = db.books.find({</span><span class=\"mtk8\">&quot;user_id&quot;</span><span class=\"mtk1\">: user_id, </span><span class=\"mtk8\">&quot;category&quot;</span><span class=\"mtk1\">: category})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> [{**book, </span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(book[</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">])} </span><span class=\"mtk15\">for</span><span class=\"mtk1\"> book </span><span class=\"mtk4\">in</span><span class=\"mtk1\"> books]</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">get_by_user_id_and_title</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user_id</span><span class=\"mtk1\">, </span><span class=\"mtk12\">title</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&quot;&quot;&quot;Get a book given its title and author&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        book = db.books.find_one({</span><span class=\"mtk8\">&quot;user_id&quot;</span><span class=\"mtk1\">: user_id, </span><span class=\"mtk8\">&quot;title&quot;</span><span class=\"mtk1\">: title})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> book:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        book[</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">] = </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(book[</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> book</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">update</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">, </span><span class=\"mtk12\">book_id</span><span class=\"mtk1\">, </span><span class=\"mtk12\">title</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">description</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">image_url</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">category</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user_id</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=\"mtk8\">&quot;&quot;&quot;Update a book&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        data={}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> title: data[</span><span class=\"mtk8\">&quot;title&quot;</span><span class=\"mtk1\">]=title</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> description: data[</span><span class=\"mtk8\">&quot;description&quot;</span><span class=\"mtk1\">]=description</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> image_url: data[</span><span class=\"mtk8\">&quot;image_url&quot;</span><span class=\"mtk1\">]=image_url</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> category: data[</span><span class=\"mtk8\">&quot;category&quot;</span><span class=\"mtk1\">]=category</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        book = db.books.update_one(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            {</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">: bson.ObjectId(book_id)},</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;$set&quot;</span><span class=\"mtk1\">: data</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\">        book = </span><span class=\"mtk4\">self</span><span class=\"mtk1\">.get_by_id(book_id)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> book</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">delete</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">, </span><span class=\"mtk12\">book_id</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&quot;&quot;&quot;Delete a book&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        book = db.books.delete_one({</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">: bson.ObjectId(book_id)})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> book</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">delete_by_user_id</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user_id</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&quot;&quot;&quot;Delete all books created by a user&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        book = db.books.delete_many({</span><span class=\"mtk8\">&quot;user_id&quot;</span><span class=\"mtk1\">: bson.ObjectId(user_id)})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> book</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">User</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&quot;&quot;&quot;User Model&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">__init__</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">create</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">, </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">email</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;&quot;</span><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 class=\"mtk8\">&quot;&quot;&quot;Create a new user&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        user = </span><span class=\"mtk4\">self</span><span class=\"mtk1\">.get_by_email(email)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> user:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        new_user = db.users.insert_one(</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;name&quot;</span><span class=\"mtk1\">: name,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;email&quot;</span><span class=\"mtk1\">: email,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">self</span><span class=\"mtk1\">.encrypt_password(password),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;active&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">True</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">self</span><span class=\"mtk1\">.get_by_id(new_user.inserted_id)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">get_all</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&quot;&quot;&quot;Get all users&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        users = db.users.find({</span><span class=\"mtk8\">&quot;active&quot;</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\">return</span><span class=\"mtk1\"> [{**user, </span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(user[</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">])} </span><span class=\"mtk15\">for</span><span class=\"mtk1\"> user </span><span class=\"mtk4\">in</span><span class=\"mtk1\"> users]</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">get_by_id</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user_id</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&quot;&quot;&quot;Get a user by id&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        user = db.users.find_one({</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">: bson.ObjectId(user_id), </span><span class=\"mtk8\">&quot;active&quot;</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\">if</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> user:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        user[</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">] = </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(user[</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        user.pop(</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> user</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">get_by_email</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</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=\"mtk8\">&quot;&quot;&quot;Get a user by email&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        user = db.users.find_one({</span><span class=\"mtk8\">&quot;email&quot;</span><span class=\"mtk1\">: email, </span><span class=\"mtk8\">&quot;active&quot;</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\">if</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> user:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        user[</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">] = </span><span class=\"mtk10\">str</span><span class=\"mtk1\">(user[</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> user</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">update</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user_id</span><span class=\"mtk1\">, </span><span class=\"mtk12\">name</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=\"mtk8\">&quot;&quot;&quot;Update a user&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        data = {}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> name:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            data[</span><span class=\"mtk8\">&quot;name&quot;</span><span class=\"mtk1\">] = name</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        user = db.users.update_one(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            {</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">: bson.ObjectId(user_id)},</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;$set&quot;</span><span class=\"mtk1\">: data</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\">        user = </span><span class=\"mtk4\">self</span><span class=\"mtk1\">.get_by_id(user_id)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> user</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">delete</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user_id</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&quot;&quot;&quot;Delete a user&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        Books().delete_by_user_id(user_id)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        user = db.users.delete_one({</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">: bson.ObjectId(user_id)})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        user = </span><span class=\"mtk4\">self</span><span class=\"mtk1\">.get_by_id(user_id)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> user</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">disable_account</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user_id</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&quot;&quot;&quot;Disable a user account&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        user = db.users.update_one(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            {</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">: bson.ObjectId(user_id)},</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            {</span><span class=\"mtk8\">&quot;$set&quot;</span><span class=\"mtk1\">: {</span><span class=\"mtk8\">&quot;active&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">False</span><span class=\"mtk1\">}}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        user = </span><span class=\"mtk4\">self</span><span class=\"mtk1\">.get_by_id(user_id)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> user</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">encrypt_password</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</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=\"mtk8\">&quot;&quot;&quot;Encrypt password&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> generate_password_hash(password)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">login</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</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=\"mtk8\">&quot;&quot;&quot;Login a user&quot;&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        user = </span><span class=\"mtk4\">self</span><span class=\"mtk1\">.get_by_email(email)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> user </span><span class=\"mtk4\">or</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> check_password_hash(user[</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\">], password):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        user.pop(</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> user</span></span></code></pre>\n<p>Here's an example of the user request:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">{</span>\n<span class=\"grvsc-line\">     &quot;name&quot; : &quot;abc xyz&quot;,</span>\n<span class=\"grvsc-line\">     &quot;email&quot; : &quot;xyz@gmail.com&quot;,</span>\n<span class=\"grvsc-line\">     &quot;password&quot; : &quot;Abc@123&quot;</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<p>Here, the name should have two words, and the password should have at least an uppercase later, a lower case letter, a digit, and a special character.</p>\n<p>And an example of the book request:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">{</span>\n<span class=\"grvsc-line\">    &quot;title&quot;:&quot;name of book&quot;,</span>\n<span class=\"grvsc-line\">    &quot;cover_image&quot;: &quot;path to image file locally&quot;,</span>\n<span class=\"grvsc-line\">    &quot;category&quot;: &quot;[&#39;romance&#39;, &#39;peotry&#39;, &#39;politics&#39;, &#39;picture book&#39;, &#39;science&#39;, &#39;fantasy&#39;, &#39;horror&#39;, &#39;thriller&#39;],</span>\n<span class=\"grvsc-line\">    &quot;description&quot;:&quot;description&quot;,</span>\n<span class=\"grvsc-line\">    &quot;user_id&quot;:&quot;user_id&quot;</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<p>While passing a book request, pass it via the <code>form-data</code> tab in Postman.</p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>This article has explained flask JWT authentication .</p>\n<p>In some cases, handling flask authentication yourself may not be good enough or efficient -- to overcome this, you can simply use third-party authentication providers like LoginRadius. You can check out this tutorial to learn how to add LoginRadius to your Flask application.</p>\n<p>You can find the complete code for this article on <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/Flask/loginRadius-flask-auth\">Github</a>. You can reach out to me on <a href=\"https://twitter.com/bkoiki950\">Twitter</a> if you've any questions.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n</style>","frontmatter":{"date":"December 09, 2021","updated_date":null,"title":"Using JWT Flask JWT Authentication- A Quick Guide","tags":["Flask","JWT","API"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/1cfc51c7d9ade423f3b1992809ba5b1b/58556/coverImage.webp","srcSet":"/static/1cfc51c7d9ade423f3b1992809ba5b1b/61e93/coverImage.webp 200w,\n/static/1cfc51c7d9ade423f3b1992809ba5b1b/1f5c5/coverImage.webp 400w,\n/static/1cfc51c7d9ade423f3b1992809ba5b1b/58556/coverImage.webp 800w,\n/static/1cfc51c7d9ade423f3b1992809ba5b1b/99238/coverImage.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Babatunde Koiki","github":"Babatunde13","avatar":null}}}},{"node":{"fields":{"slug":"/engineering/guest-post/jwt-authentication-best-practices-and-when-to-use/"},"html":"<p>One of the most used authentication standards in web applications is the JSON Web Token standard. It is mostly used for authentication, authorization, and information exchange.</p>\n<p>JSON Web tokens are made of three parts separated by dots <code>(.)</code> — and look like this typically: <code>xxxxx.yyyyy.zzzzz</code>. These correspond to the Header, the Payload, and the Signature. You can learn more about <a href=\"https://www.loginradius.com/blog/engineering/jwt/\">JWT tokens here</a>.</p>\n<p>And before using them and continuing to read this article, you might want to check the advantages compared to the session authentication method. You can learn more about <a href=\"https://www.loginradius.com/blog/engineering/guest-post/jwt-vs-sessions/\">JWTs vs. Sessions here</a>.</p>\n<h2 id=\"when-to-use-jwt-authentication\" style=\"position:relative;\"><a href=\"#when-to-use-jwt-authentication\" aria-label=\"when to use jwt authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>When to Use JWT Authentication?</h2>\n<h3 id=\"authentication\" style=\"position:relative;\"><a href=\"#authentication\" aria-label=\"authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Authentication</h3>\n<p>Authentication is done when a client successfully proves its identity via a login endpoint. If it's successful, the server will create JSON Web Token and send it in response to the client.</p>\n<p>The client will use this JWT on every request for a protected resource. </p>\n<h3 id=\"authorization\" style=\"position:relative;\"><a href=\"#authorization\" aria-label=\"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>Authorization</h3>\n<p>A server built on JWT for authorization will create a JWT when a client logs in. This JWT is signed, so any other party can’t alter it.</p>\n<p>Each time the client has access to protected resources, the server will verify that the JWT’s signature matches its payload and header to determine that the JWT is valid.</p>\n<p>Then if the JWT is successfully verified, it can grant or deny access to the resource. </p>\n<h3 id=\"data-exchanges\" style=\"position:relative;\"><a href=\"#data-exchanges\" aria-label=\"data exchanges permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Data Exchanges</h3>\n<p>JWT is also a great way to secure information transmission between parties — two servers, for example — and because you can verify the validity of the token (signature, structure, or the standards claimed in the JWT). </p>\n<h2 id=\"when-not-to-use-jwt-authentication\" style=\"position:relative;\"><a href=\"#when-not-to-use-jwt-authentication\" aria-label=\"when not to use jwt authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>When Not to Use JWT Authentication?</h2>\n<h3 id=\"revocable-tokens\" style=\"position:relative;\"><a href=\"#revocable-tokens\" aria-label=\"revocable 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>Revocable Tokens</h3>\n<p>JWT doesn’t require any lookup of the database, so revoking them before the expiration is quite difficult. </p>\n<p>Revocation is very important in many cases.</p>\n<p>For example, when logging out users or banning users, or changing permissions or passwords instantly, if the token hasn't been revoked, it might be possible for the user to continue to make requests even if this user no longer has the required authorization to do so.</p>\n<h3 id=\"sensitive-information\" style=\"position:relative;\"><a href=\"#sensitive-information\" aria-label=\"sensitive information permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Sensitive Information</h3>\n<p>JWT is usually signed to protect against data manipulation or alteration. With this, the data can be easily read or decoded.</p>\n<p>So, you can’t include sensitive information such as the user’s record or any identifier because the data is not encrypted.</p>\n<h3 id=\"cookie-size-factor\" style=\"position:relative;\"><a href=\"#cookie-size-factor\" aria-label=\"cookie size factor permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Cookie Size Factor</h3>\n<p>The size of a JWT is greater than the size of a session token. And this can quickly increase linearly as you add more data to the JWT. And because you need to send the JWT at each request, you're increasing the payload size. This can become heavily complex if there is a low-speed internet connection.</p>\n<h2 id=\"jwt-best-practices\" style=\"position:relative;\"><a href=\"#jwt-best-practices\" aria-label=\"jwt best practices permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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: Best Practices</h2>\n<h3 id=\"1-jwt-as-access-token\" style=\"position:relative;\"><a href=\"#1-jwt-as-access-token\" aria-label=\"1 jwt as access token permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1) JWT as Access Token</h3>\n<p>JWT can be used as an access token to prevent unwanted access to a protected resource. They're often used as Bearer tokens, which the API will decode and validate before sending a response.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">Authorization: Bearer &lt;token&gt;</span></code></pre>\n<h3 id=\"2-refresh-tokens-logic-with-jwt\" style=\"position:relative;\"><a href=\"#2-refresh-tokens-logic-with-jwt\" aria-label=\"2 refresh tokens logic 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>2) Refresh Tokens Logic with JWT</h3>\n<p>How do you get a new access token if this one is expired? The natural first idea is to log in again. But from a User Experience point, this can be quite painful.</p>\n<p>JWT can be used as <a href=\"https://www.loginradius.com/blog/engineering/guest-post/what-are-refresh-tokens-and-when-to-use-them/\">refresh tokens</a>; these tokens are used to retrieve a new access token.</p>\n<p>For example, when a client requests a protected resource and receives an error, which can mean that the access token has expired, the client can be issued a new access token by sending a request with a refresh token in the headers or the body.\nIf the refresh token is valid, a new access token will be created and sent as a response.</p>\n<p>Note that the refresh token is obtained at authentication and has a bigger lifetime.</p>\n<h3 id=\"3-which-signing-algorithm-to-use\" style=\"position:relative;\"><a href=\"#3-which-signing-algorithm-to-use\" aria-label=\"3 which signing algorithm to use permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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) Which Signing Algorithm to Use?</h3>\n<p>Interestingly enough, JWT can be <a href=\"https://www.loginradius.com/blog/engineering/jwt-signing-algorithms/\">signed using many different algorithms</a>. But let’s quickly talk about the <code>alg</code> value in the JWT header. When it’s decoded:</p>\n<p>The <code>alg</code> value in JWT headers simply tells you how the JWT was signed. For example, with an <code>alg</code> value of <code>RS512</code>. </p>\n<p><code>RS512 => RS 512</code> where RS is the signature algorithm and <code>SHA-512</code> is the hashing algorithm.</p>\n<p><code>SHA-512</code> will produce a <code>512-bits</code> hash while <code>SHA-256</code> will produce a <code>256-bit</code> hash. And each of these algorithms gives you 50% of their output size of security level. This means that, for example, <code>SHA-512</code> will provide you with <code>256-bits</code> security.</p>\n<p>In any case, make sure to use a minimum of <code>128-bit</code> security.</p>\n<h3 id=\"4-expiration-issued-time-and-clock-skew\" style=\"position:relative;\"><a href=\"#4-expiration-issued-time-and-clock-skew\" aria-label=\"4 expiration issued time and clock skew permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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) Expiration, Issued Time, and Clock Skew</h3>\n<p>JWTs are hard to revoke when they are created. Most of the time, you’ll have to wait until expiry. That’s why you should use a short expiration time. </p>\n<p>Additionally, you can implement your own revocation system.</p>\n<p>JWT comes with a time-based claim <code>iat</code> — issued at. It can be used to reject tokens that are too old to be used by the resource server.\nAnd clock skew specifies the allowed time difference (in seconds) between the server and the client clocks when verifying <code>exp</code> and <code>nbf</code> time-based claims. The default recommended default value is 5.</p>\n<h3 id=\"5-jwt-signature\" style=\"position:relative;\"><a href=\"#5-jwt-signature\" aria-label=\"5 jwt signature permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>5) JWT Signature</h3>\n<p>The last part of a JWT is the signature, which is simply a MAC (or Message Authentication Code). This signature is created by the server using a secret key. This secret key is an important part of the JWT signature.</p>\n<p>There are two things to respect to decrease the probability of a secret key leaking or a successful brute force attack:</p>\n<ul>\n<li>Keep the secret key <strong>secret</strong></li>\n<li>\n<p>The minimum key length must be equal to the size of bits of the hash function used along with the HMAC algorithm.</p>\n<blockquote>\n<p>\"A key of the same size as the hash output (for instance, 256 bits for \"HS256\") or larger MUST be used with this algorithm.\" - <a href=\"https://tools.ietf.org/html/rfc7518#section-3.2\">JSON Web Algorithms (RFC 7518), 3.2 HMAC with SHA-2 Functions</a></p>\n</blockquote>\n</li>\n</ul>\n<h3 id=\"6-where-to-store-the-tokens\" style=\"position:relative;\"><a href=\"#6-where-to-store-the-tokens\" aria-label=\"6 where to store the 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>6) Where to Store the Tokens?</h3>\n<p>The easiest ways to store a token on the client side are <code>localStorage</code> and <code>sessionStorage</code>. However, both are vulnerable to XSS attacks, and <code>sessionStorage</code> is cleaned if the browser is closed.</p>\n<p>A better, secure way is to store JWT in cookies. Cookies are not accessible via JavaScript, they can’t be read and written, and interestingly, they are automatically sent to the server.</p>\n<h3 id=\"7-always-use-https\" style=\"position:relative;\"><a href=\"#7-always-use-https\" aria-label=\"7 always use https permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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) Always Use HTTPS</h3>\n<p>One of the main benefits of <code>HTTPS</code> is that it comes with security and trust. <code>HTTP</code> path and query parameters are encrypted when using <code>HTTPS</code>.</p>\n<p>Then, there is no risk of someone intercepting the request, particularly the token in transit. These types of attacks are commonly called <strong>MitM</strong> (man in the middle) attacks that can be successful on compromised or insecure networks.</p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>This article discussed JWT and some best practices to fully use its potential.</p>\n<p>JWT is simply an authentication standard with its pros and cons. Thus, knowing some best practices can really help you use JWT better.</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":"October 14, 2021","updated_date":null,"title":"JWT Authentication — Best Practices and When to Use","tags":["JWT","Authentication"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/2f8d7e959c4e58511a3d83168d15cd6f/58556/cover-image.webp","srcSet":"/static/2f8d7e959c4e58511a3d83168d15cd6f/61e93/cover-image.webp 200w,\n/static/2f8d7e959c4e58511a3d83168d15cd6f/1f5c5/cover-image.webp 400w,\n/static/2f8d7e959c4e58511a3d83168d15cd6f/58556/cover-image.webp 800w,\n/static/2f8d7e959c4e58511a3d83168d15cd6f/99238/cover-image.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Kolawole Mangabo","github":"koladev32","avatar":null}}}},{"node":{"fields":{"slug":"/engineering/guest-post/jwt-vs-sessions/"},"html":"<p>In web applications, you try to decide when to use either <a href=\"https://www.loginradius.com/blog/engineering/jwt/\">JSON Web Tokens (JWTs)</a> or sessions (cookies) for authentication. When you browse the web you use HTTP, which is a stateless protocol. So, the only way to remember the states of your application is using either sessions or tokens.</p>\n<h2 id=\"goals\" style=\"position:relative;\"><a href=\"#goals\" aria-label=\"goals permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Goals</h2>\n<p>This article deep dives into:</p>\n<ul>\n<li>Differences in using sessions and JSON Web Tokens for authentication</li>\n<li>How server-side session store works</li>\n<li>Advantages of sessions over JWT</li>\n<li>Advantages of using JWT and other things concerning the structure of JWT.</li>\n</ul>\n<h2 id=\"jwt-vs-session-what-to-use\" style=\"position:relative;\"><a href=\"#jwt-vs-session-what-to-use\" aria-label=\"jwt vs session what to use permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 vs. Session: What to Use?</h2>\n<p>Deciding to choose between JWT or session is not just choosing one over the other. You need to look at some factors to determine which one to use in an application. In order to figure this out, you need to compare both approaches -- JWT and session -- to authenticate users.</p>\n<h2 id=\"comparison-jwt-and-session\" style=\"position:relative;\"><a href=\"#comparison-jwt-and-session\" aria-label=\"comparison jwt and session permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Comparison: JWT and Session</h2>\n<p>This article starts with how server-side sessions with a session store work, then looks at how client-side sessions with JWT work.</p>\n<p><img src=\"https://paper-attachments.dropbox.com/s_483BCD9E50710AD4C34073FFCB4BDCD46B2FB758D7EDCF747C5F8981B4094012_1628279671087_How+sessions+work.webp\" alt=\"authentication flow\"></p>\n<h2 id=\"how-server-side-sessions-work-with-a-session-store\" style=\"position:relative;\"><a href=\"#how-server-side-sessions-work-with-a-session-store\" aria-label=\"how server side sessions work with a session store permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Server-side Sessions Work With a Session Store</h2>\n<p>Suppose, you have a website with a login form. You enter your email ID and password, and your browser sends a request to the server. Your server compares the password hashes, and if those hashes match, a session is created with a specific session ID. Then, the server returns a cookie with the session ID and the cookie is HTTP only, so it can not be read by any javascript that is not yours. It is also secured so that the cookie is never transferred over an insecure connection; that is, something that is not encrypted. Otherwise, someone can intercept the communication, like a man in the middle attack.</p>\n<p><img src=\"https://paper-attachments.dropbox.com/s_483BCD9E50710AD4C34073FFCB4BDCD46B2FB758D7EDCF747C5F8981B4094012_1628279971421_sessionswork2.webp\" alt=\"server-side sessions with a session store\"></p>\n<p>If you make a follow-up request, your browser automatically sends this cookie along. Take a look at the session ID and fish it out.</p>\n<h2 id=\"how-client-side-sessions-work-with-jwt\" style=\"position:relative;\"><a href=\"#how-client-side-sessions-work-with-jwt\" aria-label=\"how client side sessions work 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 Client-side Sessions Work with JWT</h2>\n<p><img src=\"https://paper-attachments.dropbox.com/s_483BCD9E50710AD4C34073FFCB4BDCD46B2FB758D7EDCF747C5F8981B4094012_1628281019519_Clientside.webp\" alt=\"client-side sessions with JWT\"></p>\n<p>Instead of creating a session in your session store, you check whether the password hashes match. And if they do match, you can just create a JSON signature token and the token is signed with the secret. If someone tries to modify the payload, you will know and the signature validation will fail.</p>\n<p>You can return the web signature token that can be put in a cookie, which is way better. Because, if you don't do that, there is a possibility that a third-party javascript can access it.</p>\n<h2 id=\"problems-with-jwt-and-statelessness\" style=\"position:relative;\"><a href=\"#problems-with-jwt-and-statelessness\" aria-label=\"problems with jwt and statelessness permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Problems with JWT and Statelessness</h2>\n<p>Imagine a scenario in which a bank customer's info has been breached and the customer calls the bank to lock the account. This will be an issue if the bank uses JWT for authentication as JWT is stateless. Although you can find a workaround to do this by introducing state, it just defeats the purpose of having a JWT token in the first place, standing a chance of logging everyone out including the customer.</p>\n<p>With Sessions, logging out that one particular customer won’t be a problem at all as the customer's state is stored.</p>\n<h3 id=\"data-visibility-and-control\" style=\"position:relative;\"><a href=\"#data-visibility-and-control\" aria-label=\"data visibility and control permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Data Visibility and Control</h3>\n<p>When using server-side sessions, you don't know who is currently logged into your application as this can be useful to inflict the history of what a person is currently doing. It’s a better idea to use sessions in industries like health care, banking, insurance, or companies that deal with money. It's also good to note that JWT is signed and anyone can read it or get an idea of how data or ID is structured, or how many rows data has, which is not the case for sessions as the data is not visible to users.</p>\n<h3 id=\"bandwidth-consumption\" style=\"position:relative;\"><a href=\"#bandwidth-consumption\" aria-label=\"bandwidth consumption permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Bandwidth Consumption</h3>\n<p>Session cookies take up very little bandwidth, whereas the bandwidth consumption will be higher in the JWT-based approach because the tokens tend to get bigger and you have the signature you have to send along for each follow up request; whereas if you have the session cookie, it's really small because its just the session ID that is being sent over.</p>\n<h3 id=\"revoking-roles-and-privileges-in-jwt-and-session-based-systems\" style=\"position:relative;\"><a href=\"#revoking-roles-and-privileges-in-jwt-and-session-based-systems\" aria-label=\"revoking roles and privileges in jwt and session based systems permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Revoking Roles and Privileges in JWT and Session-based Systems</h3>\n<p>A lot of breaches that happen in companies is a result of an internal breach from an employee or insider that is stealing data or doing weird things. It is really important to be able to revoke privileges immediately. Imagine a scenario where one person is locked in and has admin rights. Say, the token is valid for ten minutes or so. If for whatever reason you don't want that person to have admin privileges anymore, you can easily revoke the person's access if you use sessions, but might find it difficult if you use JSON web tokens.</p>\n<h2 id=\"jwt-advantages\" style=\"position:relative;\"><a href=\"#jwt-advantages\" aria-label=\"jwt advantages permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>JWT: Advantages</h2>\n<p>This section discusses the advantages of using JWT over sessions and scenarios where sessions do not cut it.</p>\n<h3 id=\"scalability\" style=\"position:relative;\"><a href=\"#scalability\" aria-label=\"scalability permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Scalability</h3>\n<p>One of the “issues” with sessions is scalability. The argument is that sessions are stored in memory and servers are duplicated to handle the application load, therefore, limiting the scalability of the application. JWT, on the other hand, has higher scalability due to its statelessness. If you use a load balancer, you can easily pass along your users to several servers without worrying, as there is no state or session data stored anywhere, making it easy for gigantic scale workloads like that of Google and Facebook.</p>\n<h3 id=\"maintainability\" style=\"position:relative;\"><a href=\"#maintainability\" aria-label=\"maintainability permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Maintainability</h3>\n<p>A downside of the sessions is their maintainability, as the sessions need to be maintained. Somewhere on someone's server, a record will need to be created every time a user is authenticated. This is done in memory. The more the users are authenticated, the greater the overhead on your server. There is no need for maintainability in JWT as no state is stored, making it a better choice in this scenario.</p>\n<h3 id=\"multiple-platforms-and-domain\" style=\"position:relative;\"><a href=\"#multiple-platforms-and-domain\" aria-label=\"multiple platforms and domain permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Multiple Platforms and Domain</h3>\n<p>When using sessions in an applications, there will come a time when you need to scale or expand the data for it to be used on multiple devices. Then, you'll need to worry about things like cross-origin resource sharing or even forbidden requests.</p>\n<p>But with JWT, you don't have to bother about CORS as you can provide data to all sorts of devices and applications. Setting up a quick header configuration gets rid of any CORS problem you would have encountered.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">Access-Control-Allow-Origin: *</span></code></pre>\n<p>As long as a valid user has a valid token, data and resources are made available from any domain.</p>\n<h3 id=\"platform-independent\" style=\"position:relative;\"><a href=\"#platform-independent\" aria-label=\"platform independent permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Platform Independent</h3>\n<p>You can easily allow selective permissions for third-party applications with the help of JWT. Say, you build an application that you like to share permissions with other applications; for instance, sharing a video you watched on Facebook to friends on Instagram. You can also get creative building APIs that hand the special tokens to other applications so that user data can be accessed.</p>\n<h2 id=\"attacking-jwts-vs-session-based-authentication\" style=\"position:relative;\"><a href=\"#attacking-jwts-vs-session-based-authentication\" aria-label=\"attacking jwts vs session based authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Attacking JWTs vs. Session-based Authentication</h2>\n<p>Auth tokens are usually sent over the network and as such are vulnerable to attack. These kinds of attacks are:</p>\n<ul>\n<li>Man in the Middle attack</li>\n<li>OAuth token theft</li>\n<li>XSS</li>\n<li>CSRF</li>\n<li>Database/filesystem access</li>\n<li>Session fixation</li>\n</ul>\n<p>Although it may seem that these types of attacks are not likely to happen, it's important to take security seriously and implement appropriate measures. The vulnerability of the system is based on the cumulative probabilities of all the types of attacks. In some ways, you can mitigate the above attacks:</p>\n<ol>\n<li><strong>Man in the middle attack:</strong> You can easily protect yourself from this type of attack by using secure HTTP and secure cookies throughout the app. However, this doesn't prevent attacks that use a proxy.</li>\n<li><strong>OAuth token theft:</strong> The solution to this is to have appropriate measures in place to detect stolen refresh tokens and use only short-lived access tokens.</li>\n<li><strong>XSS attack:</strong> One way to prevent this attack is to make sure that all of the dependencies are secure. This method is time-consuming and costly.</li>\n<li><strong>Cross-site request forgery (CSRF):</strong> Prevention of CSRF attacks typically requires the use of an anti-CSRF token or SameSite cookies. However, there are other methods that you can user to solve this in a way that is seamless with the whole authentication process.</li>\n<li>\n<p><strong>Database and filesystem access:</strong> To control damage caused by unauthorized access to your database or filesystem, you could do the following:</p>\n<ul>\n<li>Store only the hashed version of the tokens that are in your database to prevent unauthorized access.</li>\n<li>If the private key is compromised, the attacker can access both the current and future sessions of the JWTs. To prevent this, all current JWTs must be changed before they are invalidated.</li>\n</ul>\n</li>\n<li><strong>Session fixation:</strong> Each time a user logs in, generate a new set of tokens for that account. This method will invalidate the old ones if needed.</li>\n</ol>\n<h3 id=\"cookies-vs-local-storage\" style=\"position:relative;\"><a href=\"#cookies-vs-local-storage\" aria-label=\"cookies vs local storage permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Cookies vs. Local Storage</h3>\n<p>Some people who use JSON web tokens return the token and store it in local storage. This can be very dangerous as third party javascript, browser extensions, and malicious CDN scripts can have access to the token. But if you put it in a cookie, no javascript access, or even you has access to it.</p>\n<p>Another thing to note is that when using cookies, you need to mitigate CSRF. Preventing it most of the time will have to do with installing a library and writing a few lines of code.</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 the article, you've learned the differences in using sessions and JSON web tokens for authentication, how serverside session store works, the advantages of sessions over JWT, and other things concerning the structure of JWT.</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":"August 26, 2021","updated_date":null,"title":"How to Authenticate Users: JWT vs. Session","tags":["Authentication","JWT","Sessions"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/3b6b3c675a1895002bda9c771b6829e2/58556/ArticleHead.webp","srcSet":"/static/3b6b3c675a1895002bda9c771b6829e2/61e93/ArticleHead.webp 200w,\n/static/3b6b3c675a1895002bda9c771b6829e2/1f5c5/ArticleHead.webp 400w,\n/static/3b6b3c675a1895002bda9c771b6829e2/58556/ArticleHead.webp 800w,\n/static/3b6b3c675a1895002bda9c771b6829e2/99238/ArticleHead.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Uma Victor","github":"uma-victor1","avatar":null}}}},{"node":{"fields":{"slug":"/engineering/implementing-authentication-on-vuejs-using-jwt/"},"html":"<p>In this tutorial, we will be covering some authentication concepts and learn about authentication and how to use JSON JWTweb tokens to authorize a Vue app. To continue in this tutorial, you should be comfortable using vue, vuex, and express.</p>\n<h2 id=\"overview\" style=\"position:relative;\"><a href=\"#overview\" aria-label=\"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>Overview</h2>\n<p>In our app, we have a login form. The user enters a username and password that is then posted to an endpoint. The flow of the app is the user opens the app, then the login page appears, the user submits the login form, which makes a post request to a login endpoint, then we check if the username and password check out, then we return a JWT and store the token in vuex and depending on the token we display a different page.</p>\n<p><img src=\"https://paper-attachments.dropbox.com/s_E8FB3BC64D80223D4CC4AFEEE119F2426D27A7EBE018696513C17DED12022079_1622019813698_AppWorkflow.webp\" alt=\"App Workflow\"></p>\n<h2 id=\"setting-up-our-vue-app\" style=\"position:relative;\"><a href=\"#setting-up-our-vue-app\" aria-label=\"setting up our vue 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>Setting up our Vue app</h2>\n<p>You can start a new project using the <a href=\"https://cli.vuejs.org/guide/installation.html\">vue cli</a>, but you have to install the CLI first by running-</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm install -g @vue/cli</span>\n<span class=\"grvsc-line\"> OR</span>\n<span class=\"grvsc-line\">yarn global add @vue/cli</span></code></pre>\n<p>after the <code>cli</code> is installed, you can create a new project by running-</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">vue create jwt-auth-app</span></code></pre>\n<p>You will then be prompted to select some basic setup. In your setup, select Babel, Linter, Vue Router, and Vuex!. That’s all we need.</p>\n<h2 id=\"setup-express-server\" style=\"position:relative;\"><a href=\"#setup-express-server\" aria-label=\"setup express server permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Setup Express Server</h2>\n<p>To set up our server, we need to install <code>cors</code>, <code>dotenv</code>, <code>express</code>, and <code>nodemon</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm install cors dotenv express</span></code></pre>\n<p>Our server.js file is simplistic in a way that we just import express, tell it what port to listen to, and return “hello world” when we hit the base URL, and then we listen on that port.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;dotenv&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">config</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">express</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;express&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">cors</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;cors&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">app</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">express</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">port</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">3000</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk11\">cors</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk12\">express</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/&#39;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">send</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Hello World!&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">listen</span><span class=\"mtk1\">(</span><span class=\"mtk12\">port</span><span class=\"mtk1\">, () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\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\">`Example app listening at http://localhost:</span><span class=\"mtk4\">${</span><span class=\"mtk12\">port</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span></code></pre>\n<h2 id=\"building-a-login-form\" style=\"position:relative;\"><a href=\"#building-a-login-form\" aria-label=\"building a login form permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Building a login form</h2>\n<p>In our views folder, we add <code>login.vue</code> and <code>welcome.vue</code> files, and in the <code>login.vue</code> file, we build out the login form. But before that, we want to add a route to our vue router so that we can navigate to the login and welcome page.\nSo for the <code>index.js</code> file of our router folder, we import the login and welcome view, and we add login and welcome routes for the components to point to.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Vue</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;vue&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">VueRouter</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;vue-router&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Login</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../views/Login.vue&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Welcome</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../views/Welcome.vue&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">Vue</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk12\">VueRouter</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">routes</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\">path:</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\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Welcom&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">component:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Welcome</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\">path:</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\">name:</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\">component:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Login</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\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">VueRouter</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">mode:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;history&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">base:</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\">BASE_URL</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">routes</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\">;</span></span></code></pre>\n<p>We can now navigate to both pages. On our welcome page, we want to check if the user is not logged in, then present the link they can click to navigate to the login page. We use a router link to achieve this.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">template</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=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Welcome</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">router-link</span><span class=\"mtk1\">  </span><span class=\"mtk12\">to</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Login</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk10\">router-link</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> </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=\"mtk17\">&lt;/</span><span class=\"mtk4\">template</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>In our login view, we scaffold our form. In the form, we are going to have two input boxes, one is the username input, and the other is a password. We then add a button with the type <code>submit</code> to submit the form. When we submit, we perform a login function in our script then set <code>preventDefault</code> on our form to stop the page from refreshing each time we click the login button.\nIn the script of our application, we model our input data by doing a two-way binding to the data state.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">template</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=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">LOGIN</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">form</span><span class=\"mtk1\"> </span><span class=\"mtk14\">@submit.prevent=&quot;login&quot;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk14\">&lt;input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">v-model</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;username&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;username&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">v-model</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;submit&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Login</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=\"mtk17\">&lt;/</span><span class=\"mtk4\">form</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">&lt;/</span><span class=\"mtk12\">template</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">export default </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><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=\"mtk15\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;&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\">}</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p><img src=\"https://paper-attachments.dropbox.com/s_E8FB3BC64D80223D4CC4AFEEE119F2426D27A7EBE018696513C17DED12022079_1622020162212_loginForm.webp\" alt=\"login form\"></p>\n<p>For the login method that runs when you click the button, we would like to perform an HTTP request to our express backend. We want to make a post request to our <code>/login</code> route we will create in our server.\nIn the fetch method, the first parameter is the URL you are sending a request to. Then the second is the object you are posting containing the headers, which contain information about the request, and the body containing the form data.</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\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">export default </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><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=\"mtk15\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;&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=\"mtk1\">  </span><span class=\"mtk12\">methods</span><span class=\"mtk1\">: {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">login</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;http://localhost:3000/login&quot;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">method:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;POST&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk8\">&quot;Content-Type&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;application/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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</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>\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\">}</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>In our server.js, we create a post request to the <code>/login</code> route and send back some <code>json</code> to test it out. Now, if we click login now, we get back a 200 ok message.</p>\n<p><em>Note: Make sure you set up</em> <code>*cors*</code> <em>so that you don't encounter an error message when hitting the</em> <code>*/login*</code> <em>route</em></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/login?&quot;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;hello ma guy&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<h2 id=\"check-if-the-username-and-password-exist\" style=\"position:relative;\"><a href=\"#check-if-the-username-and-password-exist\" aria-label=\"check if the username and password exist permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Check if the username and password exist</h2>\n<p>The next step is to check if the username or password exists in a database or somewhere else. To not waste time dealing with a database, we can use a hardcoded username and password. In the post route, if somebody tries to log in with the exact login information we just hardcoded, we want to give the person a <em>green light</em> and log the person into the application; otherwise, we throw an error.</p>\n<p>Using the login payload we got from submitting the form, we can now check if the username and password are the same; else, we throw an error and respond with a status of 403 and a wrong login information message.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">USERNAME</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;uma victor&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">PASSWORD</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;8888&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">username</span><span class=\"mtk1\"> === </span><span class=\"mtk12\">USERNAME</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">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 class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">1</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;uma victor&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;uma victor&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">403</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;wrong login information&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span></code></pre>\n<h2 id=\"jwt-authentication-in-our-app\" style=\"position:relative;\"><a href=\"#jwt-authentication-in-our-app\" aria-label=\"jwt authentication in our 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>JWT Authentication in our app</h2>\n<p>This is the interesting part of the tutorial. Now, if you provide the correct login information and it checks out, the next step is to sign a JWT web token. Let’s first install the JWT plugin.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm install jsonwebtoken</span></code></pre>\n<p>also, make sure to import it at the top of your <code>server.js</code> file</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;jsonwebtoken&quot;</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>Then when the user login is successful, we want to send a JWT that is signed. So we import the JWTpackage. Then you sign in with a unique password. In a real application, we will want to have a <code>.env</code> file where we store the secret key. Then use <code>process.env</code> to grab and use it when signing our user model. Imagine we have a user object which we got back from our database with a unique ID, name, and username.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"12\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">USERNAME</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;uma victor&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">PASSWORD</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;8888&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">username</span><span class=\"mtk1\"> === </span><span class=\"mtk12\">USERNAME</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">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 class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">1</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;uma victor&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;uma victor&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">token</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">sign</span><span class=\"mtk1\">(</span><span class=\"mtk12\">user</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\">JWT_KEY</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">token</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">user</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">403</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;wrong login information&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span></code></pre>\n<p>It is the user object we want to sign, so when you send it to the client. We can uniquely identify them. The unique ID is also very important because when a server gets a request with a token, we want to know what uniquely identifies the request.\nNow when we enter the username and password in our form, we can see in the console that our JWT token is generated but is not encrypted. </p>\n<p>You can visit jwt.io and paste in the token that was generated, and your token will be decoded and return information about your payload</p>\n<p><em>Note: The token is not encrypted, and anyone who gets access to the token can hit your server with it. Tokens normally have an expiry period of between 30 - 60 minutes</em></p>\n<h2 id=\"store-token-in-vuex\" style=\"position:relative;\"><a href=\"#store-token-in-vuex\" aria-label=\"store token in vuex permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Store Token in vuex</h2>\n<p>In our fetch method in the login view, we want to get back the token and the user and store it somewhere. Now we make our login method <code>async</code>, then we set our response to equal to the fetch method that returns the user and token, and we get back the user and token from the response.</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=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">export default </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><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=\"mtk15\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;&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=\"mtk1\">  </span><span class=\"mtk12\">methods</span><span class=\"mtk1\">: {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">login</span><span class=\"mtk1\">(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">e</span><span class=\"mtk1\">.</span><span class=\"mtk11\">preventDefault</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">response</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;http://localhost:3000/login&quot;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">method:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;POST&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk8\">&quot;Content-Type&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;application/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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</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>\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\">}</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>In our store, we add the user and token data in our state and set them to <code>null</code> initially. You can use the token to see if the user is logged in or not. If the token is <code>null</code>, then we are not logged in, but if it’s set to something, then we are probably logged in.\nWe create a <code>setUser</code> mutation in our mutation object that sets the state to the user object. We also create a <code>setToken</code> mutation to assign our token.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"14\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Vue</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;vue&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Vuex</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;vuex&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">Vue</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk12\">Vuex</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Vuex</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Store</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">user:</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\">token:</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=\"mtk12\">mutations:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">setUser</span><span class=\"mtk1\">(</span><span class=\"mtk12\">state</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">state</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=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">setToken</span><span class=\"mtk1\">(</span><span class=\"mtk12\">state</span><span class=\"mtk1\">, </span><span class=\"mtk12\">token</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">state</span><span class=\"mtk1\">.</span><span class=\"mtk12\">token</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">actions:</span><span class=\"mtk1\"> {},</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">getters:</span><span class=\"mtk1\"> {},</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span></code></pre>\n<p><em>Note: It is best practice to always call mutations from our actions, but since our mutations can easily be traced, we are calling the mutations directly</em></p>\n<p>In the login view, we can import <code>mapMutations</code> from vuex and map the <code>setUser</code> and <code>setToken</code> mutation. We can now call the mutations from the login method.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"15\"><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\">mapMutations</span><span class=\"mtk1\"> </span><span class=\"mtk4\">}</span><span class=\"mtk1\"> from &quot;vuex&quot;;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">export default </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><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=\"mtk15\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;&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=\"mtk1\">  </span><span class=\"mtk12\">methods</span><span class=\"mtk1\">: {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ...</span><span class=\"mtk11\">mapMutations</span><span class=\"mtk1\">([</span><span class=\"mtk8\">&quot;setUser&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;setToken&quot;</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=\"mtk12\">e</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">e</span><span class=\"mtk1\">.</span><span class=\"mtk11\">preventDefault</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">response</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;http://localhost:3000/login&quot;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">method:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;POST&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk8\">&quot;Content-Type&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;application/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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">user</span><span class=\"mtk1\">, </span><span class=\"mtk12\">token</span><span class=\"mtk1\"> } = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setUser</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=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setToken</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">}</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>Now that we're logged in, our state has been mutated and updated with the information from our form. But after we login, we want to redirect to our welcome page using the <code>$router.push(\"/\")</code> method to redirect to the home page, which is also our welcome page. </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"16\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">$router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">push</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/&quot;</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>// image of the welcome page here\nSince you are logged in, you don’t want the login button showing anymore on the welcome page. You can use a getter from our store to do this. We check if the token is null or not and return <code>true</code> or <code>false</code>. </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"17\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">getters: {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">isLoggedIn</span><span class=\"mtk1\">(</span><span class=\"mtk12\">state</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\">state</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">},</span></span></code></pre>\n<p>then in our welcome component template, we can use now map to our Getter and use the <code>v-if</code> directive to display the login button if <code>isLoggedIn</code> is <code>true</code> or <code>false</code></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=\"mtk17\">&lt;</span><span class=\"mtk4\">template</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\">    Welcome</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">router-link</span><span class=\"mtk1\"> </span><span class=\"mtk12\">v-if</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;!isLoggedIn&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">to</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Login</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk10\">router-link</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=\"mtk17\">&lt;/</span><span class=\"mtk4\">template</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">import </span><span class=\"mtk4\">{</span><span class=\"mtk1\"> </span><span class=\"mtk12\">mapGetters</span><span class=\"mtk1\"> </span><span class=\"mtk4\">}</span><span class=\"mtk1\"> from &quot;vuex&quot;;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">export default </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">computed</span><span class=\"mtk1\">: {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ...</span><span class=\"mtk11\">mapGetters</span><span class=\"mtk1\">([</span><span class=\"mtk8\">&quot;isLoggedIn&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">}</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>In this tutorial, we looked at how to authenticate a person using the JSON web token. We created a login form and used an express server for the login route in the application using Vue.js as a frontend framework.</p>\n<h2 id=\"resources\" style=\"position:relative;\"><a href=\"#resources\" aria-label=\"resources permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Resources</h2>\n<ul>\n<li><a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/Vuejs/AuthenticationUsingJWT\">GIthub souce code</a></li>\n<li><a href=\"https://www.loginradius.com/blog/engineering/jwt/\">What are json web token</a></li>\n</ul>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk17 { color: #808080; }\n  .dark-default-dark .mtk14 { color: #F44747; }\n</style>","frontmatter":{"date":"June 02, 2021","updated_date":null,"title":"Implementing Authentication on Vue.js using JWTtoken","tags":["Auth","JWT","Vue.js"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.8867924528301887,"src":"/static/eb6480e4e97fc3f7f136edd312b36f17/58556/coverimage.webp","srcSet":"/static/eb6480e4e97fc3f7f136edd312b36f17/61e93/coverimage.webp 200w,\n/static/eb6480e4e97fc3f7f136edd312b36f17/1f5c5/coverimage.webp 400w,\n/static/eb6480e4e97fc3f7f136edd312b36f17/58556/coverimage.webp 800w,\n/static/eb6480e4e97fc3f7f136edd312b36f17/99238/coverimage.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Uma Victor","github":"uma-victor1","avatar":null}}}},{"node":{"fields":{"slug":"/engineering/invalidating-jwt/"},"html":"<p>As we all know, JSON Web Tokens are a way of sending information between parties in a way where the sender's authenticity can be verified. It is essentially a JSON object with a signature. Using this signature, services that issue these tokens can verify that they are the ones who issued this token and thus can trust the claims which are contained within. </p>\n<p>The trustworthiness of these tokens make them popular for use in authorization and authentication scenarios:</p>\n<ul>\n<li>In authorization workflows, JSON Web Tokens are distributed to users with claims containing the resources and services that are allowed for that user. The issuing service can perform its database lookups to determine the user's authorization levels when the token is being generated and issued. Since the signature can be used to verify that the token is authentic and issued by a trusted source, for subsequent transactions using the token, the service can safely take the token at its word. This saves the service from needing to check its database for the user's relevant permissions every time a transaction is performed.</li>\n<li>In authentication workflows such as OAuth2, JSON Web Tokens are often used as part of a larger workflow, where they are useful to securely transmit information between parties. Since the resource server and authenticating server are different, these tokens ensure that the information being received by these parties is valid and authentic.</li>\n</ul>\n<p>For this post, we'll be focusing on the former use case. So having a token with trustworthy claims is great; we can take the token at its word, and trust all of the information that it has contained within as gospel. Our server is unburdened from having to potentially make database calls to verify the user's role, their permissions, their existence, or even if they're logged in. Once the server has generated the token, as far as it is concerned, no state has to be maintained regarding the validity of the token. It will expire once its expiration time included in its claim has passed.</p>\n<p>But before we go ahead and use this for all of our authorization needs, we have to remember that while JSON Web Tokens themselves are stateless, to have a robust, feasible, and controllable authorization workflow, we'll have to maintain some state one way or another.</p>\n<p>You can think of an authorization token as an elementary school hall pass. The teacher (resource server) knows that it is a legitimate hall pass because it is green, 6 cm x 12 cm and has a signature from another member of the faculty. Now imagine that you've issued a hall pass, but now you need to take it back (you've changed your mind, or the kid did something bad). Your options are:</p>\n<ul>\n<li>Go to the kid and take the pass back (browser deletes the token from its storage). However, the kid made a photocopy, and can still roam the halls with relative ease.</li>\n<li>Wait till the hall pass expires (wait till the token expiry claim passes). Green hall passes are only valid on Mondays. He can still roam the halls freely for the remainder of Monday (the horror).</li>\n<li>Change the entire format of the hall pass (change the secret used to sign the token). The crisis has been averted, but now you'll need to handicraft another 5 whole hall passes for the class.</li>\n</ul>\n<p>Other than the 3rd option which may or may not be feasible depending on your use case (most likely not), we can see that it is not possible to reliably remove or revoke a token without maintaining state. The solutions that I've looked upon Stack Overflow for invalidating these tokens boil down to relying on some form of state, one way or another. Don't get me wrong however, this is not a bad thing in my opinion. Using JSON Web Tokens can and do allow us to minimize the state that we do have to maintain, with minimal added complexity.</p>\n<p>So let's look at some ways that we can couple state and JSON Web Tokens that allow us to invalidate these tokens effectively.</p>\n<h3 id=\"token-whitelist\" style=\"position:relative;\"><a href=\"#token-whitelist\" aria-label=\"token whitelist permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Token Whitelist</h3>\n<p>We can maintain a database table containing all of the tokens issued by our server that we would like to accept as valid. This would be a 1:1 session store, with every transaction occurring requiring this table to be checked to prevent an invalidated token from being accepted. While we would not be able to reduce the amount of state being maintained on our server, JSON Web Tokens still provide us with the utility of its trusted claims (and the performance benefits of not needing to check those).</p>\n<h3 id=\"token-blacklist\" style=\"position:relative;\"><a href=\"#token-blacklist\" aria-label=\"token blacklist permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Token Blacklist</h3>\n<p>We can maintain a database table containing all of the tokens issued by our server that we do NOT want to accept as valid. Every transaction that occurs will require this table to be checked, to prevent an invalidated token from being accepted. Each record would only have to be maintained until the token itself expires. I can't think of any use case where a table of invalidated tokens would regularly be larger than a table of active tokens, so I'd imagine that the table maintained would almost always be smaller than maintaining a table of active tokens.</p>\n<h3 id=\"using-a-dynamic-secret-to-sign\" style=\"position:relative;\"><a href=\"#using-a-dynamic-secret-to-sign\" aria-label=\"using a dynamic secret to sign permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Using a Dynamic Secret to Sign</h3>\n<p>This solution still needs a database lookup, but interestingly requires no state. For this, we can use the hash of a piece of data to sign the token itself. For example, by using the hash of a user's password, when the user changes their password, subsequent transactions involving an old token will fail, as the signature will fail to be verified. The effectiveness of this, however, would depend on your requirements, as this would be limited to invalidating tokens based on changing data (such as changing roles, passwords, etc.). It would not allow you to invalidate a token whenever you want.</p>\n<h3 id=\"concluding-remarks\" style=\"position:relative;\"><a href=\"#concluding-remarks\" aria-label=\"concluding remarks permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Concluding Remarks</h3>\n<p>I think that JSON Web Tokens coupled with a token blacklist is a fantastic way to manage authorization in web applications. This allows you to leverage the benefits of these tokens in reducing the network calls needed to secure your application, reduce the amount of data you need to store to manage sessions, and do so in a reliable way without introducing too much complexity.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"January 18, 2021","updated_date":null,"title":"Invalidating JSON Web Tokens","tags":["JSON Web Tokens","JWT"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/0c11b157497c5b54f5a0149f01ce15ac/58556/unsplash.webp","srcSet":"/static/0c11b157497c5b54f5a0149f01ce15ac/61e93/unsplash.webp 200w,\n/static/0c11b157497c5b54f5a0149f01ce15ac/1f5c5/unsplash.webp 400w,\n/static/0c11b157497c5b54f5a0149f01ce15ac/58556/unsplash.webp 800w,\n/static/0c11b157497c5b54f5a0149f01ce15ac/99238/unsplash.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Nick Chim","github":"nickc95","avatar":null}}}},{"node":{"fields":{"slug":"/engineering/jwt-signing-algorithms/"},"html":"<h1 id=\"jwt-signing-algorithms\" style=\"position:relative;\"><a href=\"#jwt-signing-algorithms\" aria-label=\"jwt signing algorithms permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Signing Algorithms</h1>\n<p>When JSON Web Tokens are created, they are typically signed by its issuer. This allows the recipient of the token to validate that the token received contains all of the information encoded by the issuer unmodified and as intended.</p>\n<p>A signature is not to be mistaken for encryption! The fact that a JSON token is signed does not mean that the data enclosed is unreadable by third parties. All a signature does is ensure that the message is authentic, which it achieves by allowing the recipient to compare the data they’ve received with a trusted claim included in the data (the signature).</p>\n<p>JWTs are most commonly signed using one of two algorithms: HS256 (HMAC using SHA256), and RS256 (RSA using SHA256).</p>\n<h2 id=\"how-does-a-signature-ensure-authenticity\" style=\"position:relative;\"><a href=\"#how-does-a-signature-ensure-authenticity\" aria-label=\"how does a signature ensure authenticity permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How does a signature ensure authenticity?</h2>\n<p>A signature can only be created by someone possessing a secret key, and the original payload. Signatures are generally formed by combining the data to be signed with a secret key, either by appending them together and hashing them (HS256), or by encrypting a representation of that data (a hash) using the secret key (RS256).</p>\n<p>In both signing algorithms, the data is formatted into an immutable representation in a way that a recipient can check that the creator of the signature was in possession of that particular secret key.</p>\n<h2 id=\"hs256\" style=\"position:relative;\"><a href=\"#hs256\" aria-label=\"hs256 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>HS256</h2>\n<p>HS256 is a symmetric signing method. This means that the same secret key is used to both create and verify the signature.</p>\n<p>The issuer appends the JWT header and payload with the secret key, and hashes the result using SHA256, creating a signature. The recipient uses their copies of the secret key, JWT header and payload in the same way to reproduce the signature, checking to see if they match.</p>\n<p>Aside from some incredibly unlikely scenarios, the only way for these signatures to be consistent is if the JWT header, payload and secret shared between the two parties are identical.</p>\n<h2 id=\"rs256\" style=\"position:relative;\"><a href=\"#rs256\" aria-label=\"rs256 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>RS256</h2>\n<p>RS256 is an asymmetric encryption method. This differs from a symmetric scheme in that rather than using a single secret key, a pair of seperate keys are used to encrypt and decrypt the data.</p>\n<p>The issuer generates a hash of the JWT header and payload using SHA256, and encrypts it using the RSA encryption algorithm, and their private key. The recipient uses their public key to decrypt the signature ciphertext, and then compares it to a hash they’ve reproduced using their copy of the JWT header and payload, checking for consistency.</p>\n<p>The only way that these resulting hashes are consistent is if the JWT header and payload shared between the two parties are identical, and the public key corresponds to the private key used to encrypt the hash.</p>\n<h2 id=\"when-to-use-which\" style=\"position:relative;\"><a href=\"#when-to-use-which\" aria-label=\"when to use which permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>When to use which?</h2>\n<p>Both signing schemes are effectively secure, with HS256 being a little faster. However, given this use case, the difference in speed is not particularly relevant.</p>\n<p>The main consideration on which to use, is in my opinion the symmetric vs asymmetric property of each:</p>\n<ul>\n<li>For HS256, the secret must be shared between the sender and recipient.</li>\n<li>For RS256, the private key can be kept secret, and the public key can be freely issued.</li>\n<li>In both cases, it confirms to the recipient that the message was sent by the expected party, and was received in the form that it was in when the signature was generated.</li>\n</ul>\n<p>Having an unsecured publicly available key is useful in many cases. For example, it can be published openly on the internet as part of a metadata endpoint, allowing JWT configurators to automatically retrieve the key, making for a straightforward and automatic JWT setup. As such, RS256 may be more suitable for situations where data is exchanged between two independent parties.</p>\n<p>Having a shared secret key can however also be useful in some cases. For example, if the issuer and recipient were both managed by a single party, the two applications would be able to share configurations without having to manage two separate keys. As such, HS256 may be more suitable for situations where data is exchanged within a single party</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":"September 24, 2020","updated_date":null,"title":"JWT Signing Algorithms","tags":["JWT","JSON Web Tokens"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/2fd4c7f86c996d936d9b217235d6257d/58556/unsplash.webp","srcSet":"/static/2fd4c7f86c996d936d9b217235d6257d/61e93/unsplash.webp 200w,\n/static/2fd4c7f86c996d936d9b217235d6257d/1f5c5/unsplash.webp 400w,\n/static/2fd4c7f86c996d936d9b217235d6257d/58556/unsplash.webp 800w,\n/static/2fd4c7f86c996d936d9b217235d6257d/99238/unsplash.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Nick Chim","github":"nickc95","avatar":null}}}},{"node":{"fields":{"slug":"/engineering/jwt-authentication-with-deno/"},"html":"<p>In this blog, we’ll see how to create and validate a JWT(JSON Web Token) in Deno. For this, we’ll be using <a href=\"https://github.com/timonson/djwt\">djwt</a>, the absolute minimum library to make JSON Web Tokens in deno and <a href=\"https://deno.land/x/oak@v17.1.4\">Oak framework</a></p>\n<h2 id=\"before-you-get-started\" style=\"position:relative;\"><a href=\"#before-you-get-started\" aria-label=\"before you get started permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Before You Get Started</h2>\n<p>This tutorial assumes you have:</p>\n<ul>\n<li>A basic understanding of JavaScript and Deno</li>\n<li>Latest Deno version installed on your system</li>\n</ul>\n<h3 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?</h3>\n<p>JSON Web Token is an internet standard used to create tokens for an application. These tokens hold JSON data and are cryptographically signed. </p>\n<p>Here is how a sample Json Web Token looks like</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Im9sYXR1bmRlZ2FydWJhQGdtYWlsLmNvbSIsIm</span></code></pre>\n<p>JWT is a good way of securely sending information between parties. Because JWTs can be signed—for, you can be sure the senders are who they say they are. And, as the signature is generated using the header and the payload, you can also verify that the content hasn't been tampered with.</p>\n<p>JWT can contain user information in the payload and also can be used in the session to authenticate the user. </p>\n<p>If you want to know more about JSON Web Token, We have a very good <a href=\"/jwt/\">article</a> about it.</p>\n<h3 id=\"how-to-generate-jwt-token-in-deno\" style=\"position:relative;\"><a href=\"#how-to-generate-jwt-token-in-deno\" aria-label=\"how to generate jwt token in deno permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 generate JWT token in Deno</h3>\n<p>First, let's set up a Deno server to accept requests, for it, we are using <a href=\"https://deno.land/x/oak\">Oak framework</a>, it is quite simple and few lines of codes as you can see below.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"ts\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">// index.ts</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Application</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Router</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/x/oak/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Router</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  .</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/&quot;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">context</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;JWT Example!&quot;</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=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">app</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Application</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">routes</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">allowedMethods</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">listen</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">port:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">8000</span><span class=\"mtk1\"> });</span></span></code></pre>\n<p>Once our program is ready for accepting request Let's import djwt functions to generate JWT token, In below code we can use a secret key, expiry time for JWT token in 1 hour from the time program will run and we are using HS256 algorithm.</p>\n<p>Add the below code in index.ts and update the router as shown below, you can now get a brand new token on <code>http://localhost:8000/generate</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"ts\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">// index.ts</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\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">makeJwt</span><span class=\"mtk1\">, </span><span class=\"mtk12\">setExpiration</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Jose</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Payload</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/x/djwt/create.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">key</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;secret-key&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">payload</span><span class=\"mtk1\">: </span><span class=\"mtk10\">Payload</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">iss:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Jon Doe&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">exp:</span><span class=\"mtk1\"> </span><span class=\"mtk11\">setExpiration</span><span class=\"mtk1\">(</span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Date</span><span class=\"mtk1\">().</span><span class=\"mtk11\">getTime</span><span class=\"mtk1\">() + </span><span class=\"mtk7\">60000</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">header</span><span class=\"mtk1\">: </span><span class=\"mtk10\">Jose</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">alg:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;HS256&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">typ:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;JWT&quot;</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>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Router</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  .</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/&quot;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">context</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;JWT Example!&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=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/generate&quot;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">context</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">makeJwt</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">header</span><span class=\"mtk1\">, </span><span class=\"mtk12\">payload</span><span class=\"mtk1\">, </span><span class=\"mtk12\">key</span><span class=\"mtk1\"> }) + </span><span class=\"mtk8\">&quot;</span><span class=\"mtk6\">\\n</span><span class=\"mtk8\">&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  })</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span></code></pre>\n<h3 id=\"validating-a-jwt-token\" style=\"position:relative;\"><a href=\"#validating-a-jwt-token\" aria-label=\"validating a jwt token permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Validating a JWT token</h3>\n<p>Once you get a JWT token you can validate the token by <code>validateJwt</code> function in djwt, let us import the validateJwt and add one more route <code>/validate/:token</code></p>\n<p>Now you can verify any token by passing it to a route like - <code>http://localhost:8000/validate/jwt_token</code> (jwt_token is a placeholder, please replace it with a real JWT token)</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"ts\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">// index.ts</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\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">validateJwt</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/x/djwt/validate.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  .</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/&quot;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">context</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;JWT Example!&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=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/generate&quot;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">context</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">makeJwt</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">header</span><span class=\"mtk1\">, </span><span class=\"mtk12\">payload</span><span class=\"mtk1\">, </span><span class=\"mtk12\">key</span><span class=\"mtk1\"> }) + </span><span class=\"mtk8\">&quot;</span><span class=\"mtk6\">\\n</span><span class=\"mtk8\">&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=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/validate/:token&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">context</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> ( </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">params</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">params</span><span class=\"mtk1\">.</span><span class=\"mtk12\">token</span><span class=\"mtk1\"> && (</span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">validateJwt</span><span class=\"mtk1\">(</span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">params</span><span class=\"mtk1\">.</span><span class=\"mtk12\">token</span><span class=\"mtk1\">, </span><span class=\"mtk12\">key</span><span class=\"mtk1\">)).</span><span class=\"mtk12\">isValid</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;Valid JWT</span><span class=\"mtk6\">\\n</span><span class=\"mtk8\">&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;Invalid JWT</span><span class=\"mtk6\">\\n</span><span class=\"mtk8\">&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  });</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span></code></pre>\n<p>Now you know how to generate and verify a JWT token in Deno, you can easily use it in your application, The complete source code used in this blog can be found in this <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/Deno/JWTAuthentication\">Github Repo</a></p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk6 { color: #D7BA7D; }\n</style>","frontmatter":{"date":"July 10, 2020","updated_date":null,"title":"How to create and validate JSON Web Tokens in Deno","tags":["Deno","JWT","JSON Web Token"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.492537313432836,"src":"/static/2ca148ad6e08643634262607131d918e/58556/deno_jwt.webp","srcSet":"/static/2ca148ad6e08643634262607131d918e/61e93/deno_jwt.webp 200w,\n/static/2ca148ad6e08643634262607131d918e/1f5c5/deno_jwt.webp 400w,\n/static/2ca148ad6e08643634262607131d918e/58556/deno_jwt.webp 800w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Puneet Singh","github":"puneetsingh24","avatar":null}}}},{"node":{"fields":{"slug":"/engineering/nodejs-and-mongodb-application-authentication-by-jwt/"},"html":"<p>In this blog, we’ll be implementing authentication with JWT  in a NodeJS web application. For this, we’ll be using <strong>jsonwebtoken</strong> package </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><strong>What is JWT?</strong></h2>\n<p>JWT(JSON Web Token) is a token format. It is digitally-signed, self-contained, and compact. It provides a convenient mechanism for transferring data. JWT is not inherently secure, but the use of JWT can ensure the authenticity of the message so long as the signature is verified and the integrity of the payload can be guaranteed. JWT is often used for stateless authentication in simple use cases involving non-complex systems.</p>\n<p>Here's an example of JWT:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Im9sYXR1bmRlZ2FydWJhQGdtYWlsLmNvbSIsIm</span></code></pre>\n<p>Now, let's authenticate/protect some routes.</p>\n<p>Pre-requisites: </p>\n<ul>\n<li>Basic knowledge of HTML/JavaScript</li>\n<li>NodeJS should be installed in your system.</li>\n<li>express module for creating the server.</li>\n<li>mongoose module for MongoDB connection and queries.</li>\n<li>bcrypt module for hashing.</li>\n</ul>\n<p>you can install all required packages by using following command:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm install express mongoose bcrypt  --save</span></code></pre>\n<p>Step 1. First, create a directory structure as below :</p>\n<p><code>JWTApp</code></strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">-api</span>\n<span class=\"grvsc-line\">--models</span>\n<span class=\"grvsc-line\">----userModel.js</span>\n<span class=\"grvsc-line\">--controllers</span>\n<span class=\"grvsc-line\">----userController.js</span>\n<span class=\"grvsc-line\">--route</span>\n<span class=\"grvsc-line\">----userRoute.js</span>\n<span class=\"grvsc-line\">--server.js</span></code></pre>\n<h4 id=\"step-2-install-jsonwebtoken-packageby-using-following-command\" style=\"position:relative;\"><a href=\"#step-2-install-jsonwebtoken-packageby-using-following-command\" aria-label=\"step 2 install jsonwebtoken packageby using following command permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 2. Install “<strong>jsonwebtoken</strong>” packageby using following command</h4>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"> npm install jsonwebtoken -- save</span></code></pre>\n<h4 id=\"step-3-create-the-user-model\" style=\"position:relative;\"><a href=\"#step-3-create-the-user-model\" aria-label=\"step 3 create the user model permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>Step 3. Create the user model</strong></h4>\n<p>In the api/models folder, create a file called user userModel.js by running touch api/models/userModel.js.</p>\n<p>In this file, create a mongoose schema with the following properties:</p>\n<ul>\n<li>fullName</li>\n<li>email address</li>\n<li>password</li>\n<li>the created date</li>\n</ul>\n<p>Add the following code</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=\"mtk8\">&#39;use strict&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">mongoose</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;mongoose&#39;</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;bcrypt&#39;</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">Schema</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">mongoose</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Schema</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">/**</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"> * User Schema</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"> */</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">UserSchema</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Schema</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">String</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">trim:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">required:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">email:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">String</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">unique:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">lowercase:</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\">trim:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">required:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">hash_password:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">String</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">created:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Date</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">default:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Date</span><span class=\"mtk1\">.</span><span class=\"mtk12\">now</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">UserSchema</span><span class=\"mtk1\">.</span><span class=\"mtk12\">methods</span><span class=\"mtk1\">.</span><span class=\"mtk11\">comparePassword</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">password</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">compareSync</span><span class=\"mtk1\">(</span><span class=\"mtk12\">password</span><span class=\"mtk1\">, </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">hash_password</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=\"mtk12\">mongoose</span><span class=\"mtk1\">.</span><span class=\"mtk11\">model</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;User&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">UserSchema</span><span class=\"mtk1\">);</span></span></code></pre>\n<h4 id=\"step-4-create-the-user-handlers\" style=\"position:relative;\"><a href=\"#step-4-create-the-user-handlers\" aria-label=\"step 4 create the user 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><strong>Step 4. Create the user handlers</strong></h4>\n<p>In the <strong>api/controllers</strong> folder, create a file called user userController.js by running touch api/controllers/userController.js</p>\n<p>In the userController file, create three different handlers to handle by using the following code</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk8\">&#39;use strict&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">mongoose</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;mongoose&#39;</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;jsonwebtoken&#39;</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;bcrypt&#39;</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">User</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">mongoose</span><span class=\"mtk1\">.</span><span class=\"mtk11\">model</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;User&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">register</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">newUser</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">User</span><span class=\"mtk1\">(</span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">newUser</span><span class=\"mtk1\">.</span><span class=\"mtk12\">hash_password</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">bcrypt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">hashSync</span><span class=\"mtk1\">(</span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\">.</span><span class=\"mtk12\">password</span><span class=\"mtk1\">, </span><span class=\"mtk7\">10</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">newUser</span><span class=\"mtk1\">.</span><span class=\"mtk11\">save</span><span class=\"mtk1\">(</span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">err</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\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">400</span><span class=\"mtk1\">).</span><span class=\"mtk11\">send</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">err</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\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">hash_password</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">undefined</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">(</span><span class=\"mtk12\">user</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">sign_in</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">User</span><span class=\"mtk1\">.</span><span class=\"mtk11\">findOne</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\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\">.</span><span class=\"mtk12\">email</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }, </span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">err</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\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">) </span><span class=\"mtk15\">throw</span><span class=\"mtk1\"> </span><span class=\"mtk12\">err</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">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 class=\"mtk11\">comparePassword</span><span class=\"mtk1\">(</span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\">.</span><span class=\"mtk12\">password</span><span class=\"mtk1\">)) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;Authentication failed. Invalid user or password.&#39;</span><span class=\"mtk1\"> });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">token:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">sign</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">email:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">email</span><span class=\"mtk1\">, </span><span class=\"mtk12\">fullName:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">fullName</span><span class=\"mtk1\">, </span><span class=\"mtk12\">_id:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk12\">_id</span><span class=\"mtk1\"> }, </span><span class=\"mtk8\">&#39;RESTFULAPIs&#39;</span><span class=\"mtk1\">) });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">loginRequired</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">user</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">next</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;Unauthorized user!!&#39;</span><span class=\"mtk1\"> });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">exports</span><span class=\"mtk1\">.</span><span class=\"mtk11\">profile</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">user</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">send</span><span class=\"mtk1\">(</span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">user</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">next</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">401</span><span class=\"mtk1\">).</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;Invalid token&#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><strong><em>Note:</em> A hash password was saved in the database using bcrypt.</strong></p>\n<p>Step 6. In the <strong>api/route</strong> folder, create a file called user userRoute.js and add the following code:</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=\"mtk8\">&#39;use strict&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">module</span><span class=\"mtk1\">.</span><span class=\"mtk10\">exports</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">app</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">userHandlers</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;../controllers/userController.js&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">// todoList Routes</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/tasks&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk12\">userHandlers</span><span class=\"mtk1\">.</span><span class=\"mtk12\">loginRequired</span><span class=\"mtk1\">, </span><span class=\"mtk12\">userHandlers</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\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/auth/register&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk12\">userHandlers</span><span class=\"mtk1\">.</span><span class=\"mtk12\">register</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/auth/sign_in&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk12\">userHandlers</span><span class=\"mtk1\">.</span><span class=\"mtk12\">sign_in</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span></code></pre>\n<h4 id=\"step-7-add-the-following-code-in-serverjs\" style=\"position:relative;\"><a href=\"#step-7-add-the-following-code-in-serverjs\" aria-label=\"step 7 add the following code in serverjs permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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>Step 7. Add the following code in server.js</strong></h4>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk8\">&#39;use strict&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">express</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;express&#39;</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">app</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">express</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=\"mtk12\">process</span><span class=\"mtk1\">.</span><span class=\"mtk12\">env</span><span class=\"mtk1\">.</span><span class=\"mtk12\">PORT</span><span class=\"mtk1\"> || </span><span class=\"mtk7\">3000</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">User</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;./api/models/userModel&#39;</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">bodyParser</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;body-parser&#39;</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">jsonwebtoken</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;jsonwebtoken&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">mongoose</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;mongoose&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">option</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">socketTimeoutMS:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">30000</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">keepAlive:</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\">reconnectTries:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">30000</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">mongoURI</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\">MONGODB_URI</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">mongoose</span><span class=\"mtk1\">.</span><span class=\"mtk11\">connect</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">option</span><span class=\"mtk1\">).</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk4\">function</span><span class=\"mtk1\">(){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">//connected successfully</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}, </span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">err</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">//err handle</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk12\">bodyParser</span><span class=\"mtk1\">.</span><span class=\"mtk11\">urlencoded</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">extended:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\"> }));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk12\">bodyParser</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">headers</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">headers</span><span class=\"mtk1\">.</span><span class=\"mtk12\">authorization</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">headers</span><span class=\"mtk1\">.</span><span class=\"mtk12\">authorization</span><span class=\"mtk1\">.</span><span class=\"mtk11\">split</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39; &#39;</span><span class=\"mtk1\">)[</span><span class=\"mtk7\">0</span><span class=\"mtk1\">] === </span><span class=\"mtk8\">&#39;JWT&#39;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">jsonwebtoken</span><span class=\"mtk1\">.</span><span class=\"mtk11\">verify</span><span class=\"mtk1\">(</span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">headers</span><span class=\"mtk1\">.</span><span class=\"mtk12\">authorization</span><span class=\"mtk1\">.</span><span class=\"mtk11\">split</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39; &#39;</span><span class=\"mtk1\">)[</span><span class=\"mtk7\">1</span><span class=\"mtk1\">], </span><span class=\"mtk8\">&#39;RESTFULAPIs&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">err</span><span class=\"mtk1\">, </span><span class=\"mtk12\">decode</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">err</span><span class=\"mtk1\">) </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">user</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">undefined</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">user</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">decode</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">next</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">user</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">undefined</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">next</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">routes</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;./api/routes/userRoutes&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">routes</span><span class=\"mtk1\">(</span><span class=\"mtk12\">app</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">404</span><span class=\"mtk1\">).</span><span class=\"mtk11\">send</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">url:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">originalUrl</span><span class=\"mtk1\"> + </span><span class=\"mtk8\">&#39; not found&#39;</span><span class=\"mtk1\"> })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">listen</span><span class=\"mtk1\">(</span><span class=\"mtk12\">port</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39; RESTful API server started on: &#39;</span><span class=\"mtk1\"> + </span><span class=\"mtk12\">port</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">module</span><span class=\"mtk1\">.</span><span class=\"mtk10\">exports</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">app</span><span class=\"mtk1\">;</span></span></code></pre>\n<p>Step 9. Now you just need to run the project by using the following command and try logging by using the JWT.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm start</span></code></pre>\n<p>Step 10. Open Postman and create a post request to <strong>localhost:3000/auth/register</strong> as below: </p>\n<p><img src=\"/a6eec58240d18cb17146ca11b5d49dcd/register.webp\" alt=\"Postman register\"></p>\n<p>Step 11. After this, let’s sign with this URL <strong>localhost:3000/auth/sign_in</strong> . Enter the keys and values for email and password </p>\n<p><img src=\"/5cb1b965f14b8f3b4d254d7d310c789d/signIn.webp\" alt=\"Postman signin\"></p>\n<p>Under the value, add JWT and the token with a space between, like so:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Im9sYXR1bmRlZ2FydWJhQGdtYWlsLmNvbSIsImZ1bGxOYW1lIjoiT2xhdHVuZGUgR2FydWJhIiwiX2lkIjoiNThmMjYzNDdiMTY1YzUxODM1NDMxYTNkIiwiaWF0IjoxNDkyMjgwMTk4fQ.VcMpybz08cB5PsrMSr25En4_EwCGWZVFgciO4M-3ENE</span></code></pre>\n<p>Step 11. Then, enter the parameters for the key and value for fetching the profile. You want to create as shown below and send:</p>\n<p><img src=\"/42b50f8f60ca459023e492ce1b802845/profile.webp\" alt=\"Postman signin\"></p>\n<p>As we have seen it is fairly easy to build a JWT authentication system with NodeJS, You can found the complete code used in this tutorial <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/NodeJs/JwtAuthentication\">here</a>. </p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n</style>","frontmatter":{"date":"March 20, 2020","updated_date":null,"title":"NodeJS and MongoDB application authentication by JWT","tags":["NodeJs","JWT","MongoDB","Authentication","JSON Web Token"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.6666666666666667,"src":"/static/2b39d6f99b1ca5d4bc89d3bfccb6e29d/e9589/jwt.webp","srcSet":"/static/2b39d6f99b1ca5d4bc89d3bfccb6e29d/61e93/jwt.webp 200w,\n/static/2b39d6f99b1ca5d4bc89d3bfccb6e29d/1f5c5/jwt.webp 400w,\n/static/2b39d6f99b1ca5d4bc89d3bfccb6e29d/e9589/jwt.webp 500w","sizes":"(max-width: 500px) 100vw, 500px"}}},"author":{"id":"Ashish Sharma","github":"ashish8947","avatar":null}}}},{"node":{"fields":{"slug":"/engineering/using-jwt-with-oauth2-when-and-why/"},"html":"<h2 id=\"what-is-jwt-what-is-oauth2\" style=\"position:relative;\"><a href=\"#what-is-jwt-what-is-oauth2\" aria-label=\"what is jwt what is oauth2 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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? What is OAuth2?</h2>\n<p>JWT(Json Web Token) is a token format. It is digitally-signed, self-contained, and compact. It provides a convenient mechanism for transferring data. JWT is not inherently secure, but the use of JWT can ensure the authenticity of the message so long as the signature is verified and the integrity of the payload can be guaranteed. JWT is often used for stateless authentication in simple use cases involving non-complex systems.</p>\n<p>OAuth2 is an authorization protocol that builds upon the original OAuth protocol created in 2006, arising out of a need for authorization flows serving different kinds of applications from web and mobile apps to IoT. OAuth2 specifies the flows and standards under which authorization token exchanges should occur. OAuth2 does not encompass authentication, only authorization. For more information on OAuth2, please see <a href=\"https://tools.ietf.org/html/rfc6749\">IETF</a></p>\n<h2 id=\"using-jwt-with-oauth2\" style=\"position:relative;\"><a href=\"#using-jwt-with-oauth2\" aria-label=\"using jwt with oauth2 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Using JWT with OAuth2</h2>\n<p>JWT and OAuth2 are entirely different and serve different purposes, but they are compatible and can be used together. The OAuth2 protocol does not specify the format of the tokens, therefore JWTs can be incorporated into the usage of OAuth2.</p>\n<p>For example, the access_token returned from the OAuth2 Authorization Server could be a JWT carrying additional information in the payload. This could potentially increase performance by reducing round trips for the required information between the Resource Server and the Authorization Server. This is a good use case for incorporating JWT into OAuth2 implementations when transparent tokens are acceptable - there are scenarios requiring token opacity where this is not optimal.</p>\n<p>Another common way to use JWT in conjunction with OAuth2 is to issue two tokens: a reference token as access_token, and a JWT containing identity information in addition to that access token. In use cases where this implementation seems necessary, it is probably worth looking into OpenID Connect - an extension built upon OAuth2 and provides additional standardizations, including having an access_token and an id_token.</p>\n<p>A common misconception is that using JWT with OAuth2 increases the security of an application, this is not true. As mentioned earlier, JWT is not an inherently secure mechanism, and the security of OAuth2 is upheld through the definitions of the actors involved in the authorization process and the specific steps to be taken for this process in different use cases. Security concerns regarding OAuth2 are best addressed by choosing the appropriate OAuth2 grant flow for the application based on use case, not the token format.</p>\n<p>The advantages of using JWT in addition to OAuth2 is in increased performance and decreased process complexity when it comes to certain flows; however, this may increase development complexity. When deciding whether to use JWT on top of OAuth2, it is best to begin by considering whether the performance gain is meaningful to your application, and whether that is worth the additional work required for development.</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 11, 2019","updated_date":null,"title":"How to Use JWT with OAuth","tags":["JWT","Oauth","JSON Web Token"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/6bb161407bb0fc97a9525faaae5de564/58556/photo-1454165804606-c3d57bc86b40.webp","srcSet":"/static/6bb161407bb0fc97a9525faaae5de564/61e93/photo-1454165804606-c3d57bc86b40.webp 200w,\n/static/6bb161407bb0fc97a9525faaae5de564/1f5c5/photo-1454165804606-c3d57bc86b40.webp 400w,\n/static/6bb161407bb0fc97a9525faaae5de564/58556/photo-1454165804606-c3d57bc86b40.webp 800w,\n/static/6bb161407bb0fc97a9525faaae5de564/99238/photo-1454165804606-c3d57bc86b40.webp 1200w,\n/static/6bb161407bb0fc97a9525faaae5de564/5616c/photo-1454165804606-c3d57bc86b40.webp 1350w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Ti Zhang","github":null,"avatar":null}}}},{"node":{"fields":{"slug":"/engineering/jwt/"},"html":"<p><em>A JSON Web Token (JWT) is a JSON object that is defined in</em> <a href=\"https://tools.ietf.org/html/rfc7519\"><em>RFC 7519</em></a> <em>as a safe way</em> of <em>transmitting information between two parties. Information in the JWT is digitally-signed, so that it can be verified and trusted.</em></p>\n<p><strong>JWT Properties</strong></p>\n<ul>\n<li>Less verbose -  JWT is compact in size and can be passed in the URL, POST parameter, or HTTP header.</li>\n<li>Self-contained - JWT carries all of information needed for exchanging information and authentication.</li>\n<li>Versatile - JWT works in .NET, Python, Node.js, Java, PHP, Ruby, Go, JavaScript, and Haskell.</li>\n</ul>\n<p><strong>JWT Use Cases</strong></p>\n<ul>\n<li>Information Exchange - JWT can be used between two parties to exchange information. JWT is digitally-signed and can be used in a secure public/private key pair. Information is verified using the public key on the other end.</li>\n<li>Authentication - JWT can contain user information in the payload and can be used in the session to authenticate the user. Once authenticated, users can access protected resources in an application using the JWT included in the request. So, every request will be authenticated by verifying the JWT.</li>\n</ul>\n<p>JWT contains three parts: Header, Payload, and Signature which are separated by a dot.</p>\n<p><code>Header.Payload.Signature</code></p>\n<p><strong>Header</strong></p>\n<p>The JWT Header consists of 2 parts:</p>\n<ul>\n<li>The token type (typ): JWT </li>\n<li>Algorithm used to sign the token (alg)</li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"json\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">{  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk12\">&quot;typ&quot;</span><span class=\"mtk1\"> : </span><span class=\"mtk8\">&quot;JWT&quot;</span><span class=\"mtk1\">,  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk12\">&quot;alg&quot;</span><span class=\"mtk1\"> : </span><span class=\"mtk8\">&quot;HS256&quot;</span><span class=\"mtk1\">  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Header Algorithm Types:</p>\n<ul>\n<li>Symmetric Algorithms - This algorithm type uses a single secret key to both sign and verify the JWT token. For example: HMAC algorithms.</li>\n<li>Asymmetric Algorithms - This algorithm type uses a private key to sign the token and a public key to verify the signature. For example: RSA and ECDSA algorithms.</li>\n</ul>\n<p><strong>alg Value</strong></p>\n<p><strong>Digital Signature or MAC Algorithm</strong></p>\n<table>\n<thead>\n<tr>\n<th>Algo</th>\n<th align=\"center\">Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>HS256</td>\n<td align=\"center\">HMAC using SHA-256 hash algorithm</td>\n</tr>\n<tr>\n<td>HS384</td>\n<td align=\"center\">HMAC using SHA-384 hash algorithm</td>\n</tr>\n<tr>\n<td>HS512</td>\n<td align=\"center\">HMAC using SHA-512 hash algorithm</td>\n</tr>\n<tr>\n<td>RS256</td>\n<td align=\"center\">RSASSA using SHA-256 hash algorithm</td>\n</tr>\n<tr>\n<td>RS384</td>\n<td align=\"center\">RSASSA using SHA-384 hash algorithm</td>\n</tr>\n<tr>\n<td>RS512</td>\n<td align=\"center\">RSASSA using SHA-512 hash algorithm</td>\n</tr>\n<tr>\n<td>ES256</td>\n<td align=\"center\">ECDSA using P-256 curve and SHA-256 hash algorithm</td>\n</tr>\n<tr>\n<td>ES384</td>\n<td align=\"center\">ECDSA using P-384 curve and SHA-384 hash algorithm</td>\n</tr>\n<tr>\n<td>ES512</td>\n<td align=\"center\">ECDSA using P-521 curve and SHA-512 hash algorithm</td>\n</tr>\n</tbody>\n</table>\n<p>The Base64Url-encoded Header<strong>,</strong> which is first part of our JWT, looks like the following:</p>\n<p><code>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9</code></p>\n<p><strong>Payload</strong></p>\n<p>The Payload, also known as the JWT claim, contains all of the information we want to transmit.</p>\n<p>Different types of claims can be used to build the Payload:</p>\n<ul>\n<li><strong>Registered Claim</strong> -  These claims are optional but recommended as they contain some metadata about the token:</li>\n</ul>\n<table>\n<thead>\n<tr>\n<th>Code</th>\n<th>Name</th>\n<th align=\"center\">Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>iss</td>\n<td>issuer</td>\n<td align=\"center\">Identifies the principal that issued the JWT.</td>\n</tr>\n<tr>\n<td>sub</td>\n<td>subject</td>\n<td align=\"center\">Identifies the principal that is the subject of the JWT.</td>\n</tr>\n<tr>\n<td>aud</td>\n<td>audience</td>\n<td align=\"center\">Identifies the recipients that the JWT is intended for.</td>\n</tr>\n<tr>\n<td>exp</td>\n<td>Expiration time</td>\n<td align=\"center\">Identifies the expiration time on or after which the JWT MUST NOT be accepted for processing.</td>\n</tr>\n<tr>\n<td>nbf</td>\n<td>Not before</td>\n<td align=\"center\">Identifies the time before which the JWT MUST NOT be accepted for processing.</td>\n</tr>\n<tr>\n<td>iat</td>\n<td>Issue at</td>\n<td align=\"center\">Identifies the time at which the JWT was issued.</td>\n</tr>\n<tr>\n<td>jti</td>\n<td>JWT id</td>\n<td align=\"center\">Unique identifier for the JWT, can be used to prevent the JWT from being replayed.</td>\n</tr>\n</tbody>\n</table>\n<ul>\n<li><strong>Public Claim</strong> - These claims are defined by you, such as user name, and other important information.</li>\n<li><strong>Private Claim</strong> - A producer and consumer may agree to use claim names that are private. These are subject to collision, so use them with caution.</li>\n</ul>\n<p>Example Payload:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"json\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">{  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk12\">&quot;sub&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;1234567890&quot;</span><span class=\"mtk1\">,  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk12\">&quot;name&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Frank Emic&quot;</span><span class=\"mtk1\">,  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk12\">&quot;jti&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;4b5fcea6-2a5e-4a9d-97f2-3d8631ea2c5a&quot;</span><span class=\"mtk1\">,  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk12\">&quot;iat&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk7\">1521191902</span><span class=\"mtk1\">,  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk12\">&quot;exp&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk7\">1521195630</span><span class=\"mtk1\">  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>This example contains a combination of registered and public claims. “sub”,”jti”,”iat”, and “exp” are registered claims and “name” is a public claim.</p>\n<p>The Base64Url-encoded Payload, which is the second part of our JWT, looks like the following:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"json\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">eyJzdWIiOiIxMjM</span><span class=\"mtk7\">0</span><span class=\"mtk1\">NTY</span><span class=\"mtk7\">3</span><span class=\"mtk1\">ODkwIiwibmFtZSI</span><span class=\"mtk7\">6</span><span class=\"mtk1\">IkZyYW</span><span class=\"mtk7\">5</span><span class=\"mtk1\">rIEVtaWMiL  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">CJqdGkiOiI</span><span class=\"mtk7\">0</span><span class=\"mtk1\">YjVmY</span><span class=\"mtk7\">2</span><span class=\"mtk1\">VhNi</span><span class=\"mtk7\">0</span><span class=\"mtk1\">yYTVlLTRhOWQtOTdmMi</span><span class=\"mtk7\">0</span><span class=\"mtk1\">zZDg</span><span class=\"mtk7\">2</span><span class=\"mtk1\">MzFlYTJjNWEiLCJpYXQiOjE</span><span class=\"mtk7\">1</span><span class=\"mtk1\">MjExOTE</span><span class=\"mtk7\">5</span><span class=\"mtk1\">MDIsImV</span><span class=\"mtk7\">4</span><span class=\"mtk1\">cCI</span><span class=\"mtk7\">6</span><span class=\"mtk1\">MTUyMTE</span><span class=\"mtk7\">5</span><span class=\"mtk1\">NTYzMH</span><span class=\"mtk7\">0</span></span></code></pre>\n<p><strong>Signature</strong></p>\n<p>The final part of our JWT is the Signature. To create the Signature, we need 3 components:</p>\n<ul>\n<li>Header</li>\n<li>Payload</li>\n<li>Algorithm used to sign the Header and Payload</li>\n</ul>\n<p>var encodedString = base64UrlEncode(header) + \".\" + base64UrlEncode(payload);<br>\nHMACSHA256(encodedString, 'secret');</p>\n<p>The secret is the Signature held by the server in order to verify tokens and sign new ones.</p>\n<p>The above Base64Url-encoded Header and Payload are combined with a dot, and then digitally-signed using the secret. This generates the Signature as the third part of the our JWT:</p>\n<p>wGDoDSxfKj3Ns379NVxocwM9TOiwxhxWl</p>\n<p><strong>Putting It All Together</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"json\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">eyJhbGciOiJIUzI</span><span class=\"mtk7\">1</span><span class=\"mtk1\">NiIsInR</span><span class=\"mtk7\">5</span><span class=\"mtk1\">cCI</span><span class=\"mtk7\">6</span><span class=\"mtk1\">IkpXVCJ</span><span class=\"mtk7\">9</span><span class=\"mtk1\">.eyJzdWIiOiIxMjM</span><span class=\"mtk7\">0</span><span class=\"mtk1\">NTY</span><span class=\"mtk7\">3</span><span class=\"mtk1\">ODkwIiwibmFtZSI</span><span class=\"mtk7\">6</span><span class=\"mtk1\">IkZyYW</span><span class=\"mtk7\">5</span><span class=\"mtk1\">rIEVtaWMiL  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">CJqdGkiOiI</span><span class=\"mtk7\">0</span><span class=\"mtk1\">YjVmY</span><span class=\"mtk7\">2</span><span class=\"mtk1\">VhNi</span><span class=\"mtk7\">0</span><span class=\"mtk1\">yYTVlLTRhOWQtOTdmMi</span><span class=\"mtk7\">0</span><span class=\"mtk1\">zZDg</span><span class=\"mtk7\">2</span><span class=\"mtk1\">MzFlYTJjNWEiLCJpYXQiOjE</span><span class=\"mtk7\">1</span><span class=\"mtk1\">MjExOTE</span><span class=\"mtk7\">5</span><span class=\"mtk1\">MDIsImV</span><span class=\"mtk7\">4</span><span class=\"mtk1\">cCI</span><span class=\"mtk7\">6</span><span class=\"mtk1\">MTUyMTE</span><span class=\"mtk7\">5</span><span class=\"mtk1\">NTYzMH</span><span class=\"mtk7\">0</span><span class=\"mtk1\">.wGDoDSxfKj</span><span class=\"mtk7\">3</span><span class=\"mtk1\">Ns</span><span class=\"mtk7\">379</span><span class=\"mtk1\">NVxocwM</span><span class=\"mtk7\">9</span><span class=\"mtk1\">TOiwxhxWl</span></span></code></pre>\n<p>This is our final JWT, containing the Header, Payload, and Signature joined together with dots. It can be passed as a URL parameter, a POST parameter, or in the  HTTP header to authenticate or exchange information.</p>\n<p>Note: JWT does not hide information; it just encodes information using the digitally-signed signature and verifies that the information has not been altered over the network. So, do not add any sensitive information in the JWT claim.</p>\n<p><strong>Conclusion</strong></p>\n<p>JWT comprises three encoded parts: Header, Payload, and Signature. It can be passed as a URL or POST parameter, or in an HTTP header. Due to JWT's lightweight, self-containing, and versatile strucutre, it remains a popular tool for information exchange and authentication.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n</style>","frontmatter":{"date":"July 11, 2018","updated_date":null,"title":"What is JSON Web Token","tags":["JWT","JSON Web Token"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7699115044247788,"src":"/static/fca016963236696b6d07a52d211c1354/58556/jwt.webp","srcSet":"/static/fca016963236696b6d07a52d211c1354/61e93/jwt.webp 200w,\n/static/fca016963236696b6d07a52d211c1354/1f5c5/jwt.webp 400w,\n/static/fca016963236696b6d07a52d211c1354/58556/jwt.webp 800w,\n/static/fca016963236696b6d07a52d211c1354/99238/jwt.webp 1200w,\n/static/fca016963236696b6d07a52d211c1354/135cd/jwt.webp 1280w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Mayank Agarwal","github":"mayankagrwal","avatar":null}}}},{"node":{"fields":{"slug":"/engineering/alternate-authentication-asp/"},"html":"<p><strong>Introduction</strong></p>\n<p>Authentication and authorization both are most important things for any system and application. This blog starts with authentication and authorization concepts and after that explains the three default important ways and three custom authentication ways for doing authentication and authorization i.e. windows, forms ,passport, multipass, JWT  and SAML authentication. Plus, in this blog I will explain some fundamental concepts about the different authentication system.</p>\n<p><strong>Authentication and Authorization</strong></p>\n<p>Authentication is the process for checking the identity of a user based on the user’s credentials. Generally, user’s credentials are  in the form of user ID and password, and we check their credentials from database or equivalent alternative, if it exists then user is a valid candidate for next process - authorization.</p>\n<p>Authorization also known as “Permission Control” will come after authentication. Authorization is the process of deciding what kind of resource a user can access based on their identity and checking whether the authenticated user has sufficient rights to access the requested resources. Typically a resource can be an ASP.NET web page, media files (MP4, GIF, JPEG etc), compressed file (ZIP, RAR) etc.</p>\n<p><strong>ASP.NET default authentication Providers</strong></p>\n<p><strong>1. Form Authentication</strong></p>\n<p>Normally, form authentication is based on cookies, the authentication and permission settings are stored in cookies. However, we can also use form authentication without cookies, and in cookie-less form authentication we can use query string for passing user details. Remember, the key concept is always ONLY allow the user with correct credential also enough permission to view certain resources, so we need to capture their information and compare with what we have stored in the database. And no matter what kind of form authentication we use, after we receive the data on server end, we will compare them with the data stored in any storage method/provider. For example, we can store username and password in the web.config file, a JSON file, or a database table.</p>\n<p>Forms authentication flow:</p>\n<ol>\n<li>When a user requests a page for the application, ASP.NET checks session cookie. If the cookie exists and valid, ASP.NET assumes the user is authenticated and processes the request.</li>\n<li>If session cookies does not exists or not valid then it redirect to login form.</li>\n<li>User will enter username and password and if they are valid then he will get authenticated and authorized.</li>\n</ol>\n<p> <strong>2. Passport Authentication</strong></p>\n<p>Passport authentication is a centralized authentication service provided by Microsoft. The .NET Passport single sign-in service. When we use passport authentication then user authentication in your application is managed by Microsoft's passport service. Passport authentication uses encrypted cookies to manage the authentication.</p>\n<p><strong>How Password authentication works</strong> Users do not need to retype their sign-in name and password when moving from site to site. Those .NET Passport–enabled sites will issue a set of encrypted cookies in the .NET Passport central servers' domain to facilitate silent and seamless sign-in across sites. In some cases, sites owners will first redirect their end-users to .NET Passport sign-in and to authenticate upon first viewing of their site. If the users are logged in already, they'll get authenticated by ASP.NET, and if they are not logged in they will get redirected to passport servers (i.e hotmail, Live etc.)  to login first. If user successfully authenticates himself, it will return a token to your website.</p>\n<p><strong>3. Windows Authentication</strong></p>\n<p>We use windows authentication when we are creating a web application for a limited number of users who already have Windows account and this type of authentication is quite useful in an intranet environment. This authentication method uses local users windows account 'credentials' for to validate the user. Dot Net web application generally hosted on IIS(Internet Information Server) so the requests go directly to IIS to provide the authentication process in a Windows-based authentication model.</p>\n<p>The entire responsibility of authentication is done by IIS. It first takes the user’s credentials from the domain login. If this process fails, IIS displays an alert dialog box so the user can enter or re-enter his login information.</p>\n<p>Windows authentication have some advantages and disadvantages:</p>\n<p><strong>Windows authentication Advantage</strong></p>\n<ol>\n<li>Developers need to write less line of code for managing user's authentication.</li>\n<li>Users can use their existing windows accounts for login.</li>\n</ol>\n<p><strong>Windows authentication dis-Advantage</strong></p>\n<ol>\n<li>You can't control windows authentication process.</li>\n<li>Windows authentication only works on Microsoft OS you can't use it on others OS.</li>\n</ol>\n<p> <strong>4. Custom authentication Provider</strong></p>\n<ol>\n<li><strong>Multipass</strong></li>\n</ol>\n<p>Multipass authentication is a single sign on authentication. Suppose you have multiple sites and you want to create a single account for a user on both sites then you can use Single Sign-On. Single Sign-On is authentication system it allow user to share his authentication details with your there site. This allows a seamless experience for your users without forcing them to create a separate account on your second site. A multipass is simply a hash of keys and values, provided as an AES encrypted JSON hash.</p>\n<ol start=\"2\">\n<li><strong>JWT (JSON Web token)</strong></li>\n</ol>\n<p>JWTs represent a set of claims as a JSON object that is encoded in a JWS and/or JWE structure. This JSON object is called “JWT Claims Set”. The JSON object consists of zero or more name/value pairs (or members), where the names are strings and the values are arbitrary JSON values. These members are the claims represented by the JWT.</p>\n<p>Your JWTs can contain any information you want; the user's name, birthdate, email, etc. You do this with claims based authorization. You then just tell your provider to make a JWT with these claims from the claims principle.</p>\n<ol start=\"3\">\n<li><strong>SAML (Security Assertion Markup Language)</strong></li>\n</ol>\n<p>SAML - Security Assertion Markup Language SAML. SAML is developed by the Security Services Technical Committee of \"Organization for the Advancement of Structured Information Standards\" (OASIS). SAML is an XML-based framework for exchanging user authentication. The purpose of SAML is to enable Single Sign-On for web applications across various domains.</p>\n<p>SAML have three components: assertions, protocol, and binding. Assertions are authentication, attribute, and authorization. Authentication assertion validates the user's identity. Attribute assertion contains specific information about the user. And authorization assertion identifies user role and permissions.</p>\n<p>SAML works with multiple protocols including Hypertext Transfer Protocol (HTTP), Simple Mail Transfer Protocol (SMTP), File Transfer Protocol (FTP) and also supports SOAP</p>\n<p><strong>Summary</strong></p>\n<p>Different authentication methods are available, and website’s owner always gets confused about which authentication method they should use, here I have explained some of the popular authentication and authorization methods, hope it made it a little bit clear for you. And I will provide some in-depth details about each type of authentication in my next blog, <strong>happy coding</strong>.</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":"October 01, 2015","updated_date":null,"title":"Types of Authentication in Asp.Net","tags":["Engineering","Authentication","Asp.Net","Multipass","JWT","JSON Web Token"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/051582b8bfe0e3796cdccd575e275a97/e7487/alternate-authentication-asp-dot-net1-150x150.webp","srcSet":"/static/051582b8bfe0e3796cdccd575e275a97/e7487/alternate-authentication-asp-dot-net1-150x150.webp 150w","sizes":"(max-width: 150px) 100vw, 150px"}}},"author":{"id":"Team LoginRadius","github":"LoginRadius","avatar":null}}}}]}},"pageContext":{"tag":"JWT"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}