{"componentChunkName":"component---src-templates-blog-list-template-js","path":"/engineering/34","result":{"data":{"allMarkdownRemark":{"edges":[{"node":{"excerpt":"What are HTTP Security Headers ? When we visit any website in the browser, the browser sends some request headers to the server and the…","fields":{"slug":"/engineering/http-security-headers/"},"html":"<h3 id=\"what-are-http-security-headers-\" style=\"position:relative;\"><a href=\"#what-are-http-security-headers-\" aria-label=\"what are http security headers  permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What are HTTP Security Headers ?</h3>\n<p>When we visit any website in the browser, the browser sends some request headers to the server and the server responds with HTTP response headers. These headers are used by the client and server to share information as a part of the HTTP protocol. Browsers have defined behavior of the web page according to these headers during communication with the server. These headers are mainly a combination of key-value pairs separated by a colon <code>:</code>. There are many HTTP headers, but here I'm covering some very useful web security headers, which will improve your website security. </p>\n<h3 id=\"why-http-security-headers-are-necessary-\" style=\"position:relative;\"><a href=\"#why-http-security-headers-are-necessary-\" aria-label=\"why http security headers are necessary  permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 HTTP Security Headers are necessary ?</h3>\n<p>As you know, nowadays too many data breaches are happening, many websites are hacked due to misconfiguration or lack of protection. These security headers will protect your website from some common attacks like XSS, code injection, clickjacking, etc. Additionally these headers increases your website SEO score.</p>\n<h4 id=\"1-enforcing-https-http-strict-transport-security-hsts\" style=\"position:relative;\"><a href=\"#1-enforcing-https-http-strict-transport-security-hsts\" aria-label=\"1 enforcing https http strict transport security hsts permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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. Enforcing HTTPS (HTTP Strict Transport Security (HSTS))</h4>\n<p>HTTP Strict Transport Security security header helps to protect websites against man-in-the-middle attacks and cookie hijacking. Let's say, you have one website <code>www.example.com</code> and you have purchased SSL certification for migrating your website from HTTP to HTTPS. Now suppose old users are still opening your website using the HTTP, so they may redirect your HTTP users to HTTPS via redirection as a solution. Since visitors may first communicate with the non-encrypted version of the site before being redirected. This creates an opportunity for a man-in-the-middle attack. The HTTP Strict Transport Security header informs the browser that it should never load a site using HTTP and should automatically convert all attempts to access the site using HTTP to HTTPS requests.</p>\n<h5 id=\"syntax\" style=\"position:relative;\"><a href=\"#syntax\" aria-label=\"syntax permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Syntax</h5>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">  Strict-Transport-Security: max-age=&lt;expire-time&gt;</span>\n<span class=\"grvsc-line\">  Strict-Transport-Security: max-age=&lt;expire-time&gt;; includeSubDomains</span>\n<span class=\"grvsc-line\">  Strict-Transport-Security: max-age=&lt;expire-time&gt;; preload</span></code></pre>\n<h5 id=\"hsts-directives-\" style=\"position:relative;\"><a href=\"#hsts-directives-\" aria-label=\"hsts directives  permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>HSTS directives :</h5>\n<table>\n<thead>\n<tr>\n<th>Directives</th>\n<th>Explanation</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>max-age=&#x3C;expire-time></code></td>\n<td>This directive allows us to specify the amount of time (in seconds) that the content of the header will be stored in the browser cache.</td>\n</tr>\n<tr>\n<td><code>includeSubDomains</code></td>\n<td>If this optional parameter is specified, this rule applies to all of the site's subdomains as well.</td>\n</tr>\n<tr>\n<td><code>Preload</code></td>\n<td>This is not part of the specifications. Please see the Preloading Strict Transport Security</td>\n</tr>\n</tbody>\n</table>\n<h4 id=\"2-cross-site-scripting-protection-x-xss\" style=\"position:relative;\"><a href=\"#2-cross-site-scripting-protection-x-xss\" aria-label=\"2 cross site scripting protection x xss permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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. Cross-Site Scripting Protection (X-XSS)</h4>\n<p>X-XSS header helps protect websites against script injection attacks. When an attacker injects malicious JavaScript code into an HTTP request for accessing confidential information such as session cookies, at that time HTTP X-XSS-Protection header can stop the browsers from loading suce web pages, whenever any detect is reflected cross-site scripting (XSS) attacks. XSS is a very common and effective attack.</p>\n<h4 id=\"syntax-1\" style=\"position:relative;\"><a href=\"#syntax-1\" aria-label=\"syntax 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>Syntax</h4>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">  X-XSS-Protection: 0 </span>\n<span class=\"grvsc-line\">  X-XSS-Protection: 1 </span>\n<span class=\"grvsc-line\">  X-XSS-Protection: 1; mode=block </span>\n<span class=\"grvsc-line\">  X-XSS-Protection: 1; report=&lt;reporting-uri&gt;</span></code></pre>\n<h5 id=\"x-xss-protection-directives\" style=\"position:relative;\"><a href=\"#x-xss-protection-directives\" aria-label=\"x xss protection directives permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>X-XSS-Protection directives:</h5>\n<table>\n<thead>\n<tr>\n<th>Attribute</th>\n<th>Description</th>\n<th></th>\n<th></th>\n<th></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>0</code></td>\n<td>Disable the XSS Filtering</td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td><code>1</code></td>\n<td>Enable the XSS Filtering and remove the unsafe part</td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td><code>1; mode=block</code></td>\n<td>Browser prevents the entire page from rendering when an XSS attack is detected.</td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td><code>1; report=&#x3C;reporting-URI> (Chromium only)</code></td>\n<td>When a cross-site scripting attack is detected, the browser will remove the unsafe parts from the page and report the violation on the reporting URL.</td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n</tbody>\n</table>\n<h4 id=\"3-website-iframe-protection\" style=\"position:relative;\"><a href=\"#3-website-iframe-protection\" aria-label=\"3 website iframe protection permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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. Website IFrame Protection</h4>\n<p>The X-Frame-Options HTTP response header can be used to instruct the browser whether a web page should be allowed to render a <code>&#x3C;frame>, &#x3C;iframe>, &#x3C;embed> or &#x3C;object></code>  element on website or not.</p>\n<p>This header protects users against ClickJacking attacks. An attacker uses multiple tricks to trick the user into clicking something different than what they think they’re clicking.</p>\n<h4 id=\"syntax-2\" style=\"position:relative;\"><a href=\"#syntax-2\" aria-label=\"syntax 2 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Syntax</h4>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">  X-Frame-Options: DENY </span>\n<span class=\"grvsc-line\">  X-Frame-Options: SAMEORIGIN</span></code></pre>\n<h4 id=\"x-frame-options-directives-include-the-following\" style=\"position:relative;\"><a href=\"#x-frame-options-directives-include-the-following\" aria-label=\"x frame options directives include the following permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>X-Frame-Options directives include the following:</h4>\n<table>\n<thead>\n<tr>\n<th>Directives</th>\n<th>Explanation</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>DENY</code></td>\n<td>This will not allow to page rendering in the <code>&#x3C;frame>, &#x3C;iframe>, &#x3C;embed> or &#x3C;object></code></td>\n</tr>\n<tr>\n<td><code>SAMEORIGIN</code></td>\n<td>This will allow the page to only be displayed in a <code>&#x3C;frame>, &#x3C;iframe>, &#x3C;embed> or &#x3C;object></code> on the same origin.</td>\n</tr>\n</tbody>\n</table>\n<h4 id=\"4-preventing-content-type-sniffing\" style=\"position:relative;\"><a href=\"#4-preventing-content-type-sniffing\" aria-label=\"4 preventing content type sniffing permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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. Preventing Content-Type Sniffing</h4>\n<p><strong>X-Content-Type-Options</strong> response header prevents the browser from MIME-sniffing a response away from the declared content-type. A MIME-sniffing vulnerability allows an attacker to inject a malicious resource, such as a malicious executable script, Suppose an attacker changes the response for an innocent resource, such as an image. With MIME sniffing, the browser will ignore the declared image content type, and instead of rendering an image will execute the malicious script. </p>\n<p>Syntax </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">  X-Content-Type-Options: nosniff </span></code></pre>\n<h4 id=\"x-content-type-options-directives\" style=\"position:relative;\"><a href=\"#x-content-type-options-directives\" aria-label=\"x content type options directives permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>X-Content-Type-Options directives:</h4>\n<p><code>nosniff</code> - Blocks a request if the request destination is of type:</p>\n<h4 id=\"6-content-security-policy\" style=\"position:relative;\"><a href=\"#6-content-security-policy\" aria-label=\"6 content security policy permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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. Content Security Policy</h4>\n<p>Content-Security-Policy header is used to instruct the browser to load only the allowed content defined in the policy. This uses the whitelisting approach which tells the browser from where to load the images, scripts, CSS, applets, etc. If implemented properly, this policy prevents the exploitation of Cross-Site Scripting (XSS), ClickJacking, and HTML injection attacks.</p>\n<h4 id=\"syntax-3\" style=\"position:relative;\"><a href=\"#syntax-3\" aria-label=\"syntax 3 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Syntax</h4>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">  Content-Security-Policy: &lt;policy-directive&gt;; &lt;policy-directive&gt;</span></code></pre>\n<p>More information about the Content Security policy can be found on  <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy\">Mozilla’s website </a>.</p>\n<h3 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</h3>\n<p>As a web developer, you can follow this guide for adding security headers to your website. HTTP headers can be configured on the server to enhance the overall security of the web application. You can easily validate your website security headers. Multiple free online tools are available to check the same:</p>\n<ul>\n<li><a href=\"https://securityheaders.com/\">Security Headers</a></li>\n<li><a href=\"https://www.serpworx.com/check-security-headers/\">Serpworx</a></li>\n</ul>\n<p>These headers reduce the potential vulnerabilities of the application. Alongside these headers will add one layer of security still we need to add more layer's of security in our web 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</style>","frontmatter":{"date":"July 15, 2020","updated_date":null,"description":"HTTP security headers are a fundamental part of website security. Upon implementation, they protect you against the types of attacks that your site is most likely to come across. These headers protect against XSS, code injection, clickjacking, etc. This article explains most commonly used HTTP headers in context to application security","title":"HTTP Security Headers","tags":["Security","HTTP Headers"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/4bea535329516b2e7baca9bfc373ccfc/991d2/http-security-headers.webp","srcSet":"/static/4bea535329516b2e7baca9bfc373ccfc/61e93/http-security-headers.webp 200w,\n/static/4bea535329516b2e7baca9bfc373ccfc/1f5c5/http-security-headers.webp 400w,\n/static/4bea535329516b2e7baca9bfc373ccfc/991d2/http-security-headers.webp 640w","sizes":"(max-width: 640px) 100vw, 640px"}}},"author":{"id":"Vijay Singh Shekhawat","github":"code-vj","avatar":null}}}},{"node":{"excerpt":"Have you ever heard of SonarQube? Would you like to know What it is? And how to use it? And its benefits to the production phase of software…","fields":{"slug":"/engineering/sonarqube/"},"html":"<p>Have you ever heard of SonarQube? Would you like to know What it is? And how to use it? And its benefits to the production phase of software development. Then you are at the right place; in this tutorial of SonarQube, I will give you a walkthrough of every aspect of SonarQube.</p>\n<p>Let's dive in!!!</p>\n<h2 id=\"what-is-sonarqube\" style=\"position:relative;\"><a href=\"#what-is-sonarqube\" aria-label=\"what is sonarqube permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 SonarQube?</h2>\n<p>SonarQube is an open-source platform developed by SonarSource for continuous inspection of code quality. Sonar does static code analysis, which provides a detailed report of bugs, code smells, vulnerabilities, code duplications. </p>\n<p>It supports 25+ major programming languages through built-in rulesets and can also be extended with various plugins.</p>\n<h2 id=\"benefits-of-sonarqube\" style=\"position:relative;\"><a href=\"#benefits-of-sonarqube\" aria-label=\"benefits of sonarqube permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 SonarQube</h2>\n<ol>\n<li><strong>Sustainability</strong> - Reduces complexity, possible vulnerabilities, and code duplications, optimising the life of applications.</li>\n<li><strong>Increase productivity</strong> - Reduces the scale, cost of maintenance, and risk of the application; as such, it removes the need to spend more time changing the code</li>\n<li><strong>Quality code</strong> - Code quality control is an inseparable part of the process of software development.</li>\n<li><strong>Detect Errors</strong> - Detects errors in the code and alerts developers to fix them automatically before submitting them for output.</li>\n<li><strong>Increase consistency</strong> - Determines where the code criteria are breached and enhances the quality</li>\n<li><strong>Business scaling</strong> - No restriction on the number of projects to be evaluated</li>\n<li><strong>Enhance developer skills</strong> - Regular feedback on quality problems helps developers to improve their coding skills</li>\n</ol>\n<h2 id=\"why-sonarqube\" style=\"position:relative;\"><a href=\"#why-sonarqube\" aria-label=\"why sonarqube permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 SonarQube?</h2>\n<p>Developers <a href=\"/agile-development-team/\">working with hard deadlines</a> to deliver the required functionality to the customer. It is so important for developers that many times they compromise with the code quality, potential bugs, code duplications, and bad distribution of complexity.</p>\n<p>Additionally, they tend to leave unused variables, methods, etc. In this scenario, the code would work in the desired way.</p>\n<p>Do you think this is a proper way to deliver functionality? </p>\n<p>The answer is NO.</p>\n<p>To avoid these issues in code, developers should always follow the good coding practice, but sometimes it is not possible to follow the rules and maintain the good quality as there may be many reasons.</p>\n<p>In order to achieve continuous code integration and deployment, developers need a tool that not only works once to check and tell them the problems in the code but also to track and control the code to check continuous code quality. To satisfy all these requirements, here comes SonarQube in the picture.</p>\n<h2 id=\"how-to-setup-and-use-the-sonarqube-plugin\" style=\"position:relative;\"><a href=\"#how-to-setup-and-use-the-sonarqube-plugin\" aria-label=\"how to setup and use the sonarqube plugin permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 setup and use the sonarqube plugin</h2>\n<p>This section will explain the steps or procedures to configure the sonarqube plugin for all the major programming languages.</p>\n<h3 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:</h3>\n<p>The only prerequisite for running SonarQube is to have Java (Oracle JRE 11 or OpenJDK 11) installed on your machine. [<a href=\"https://docs.sonarsource.com/sonarqube-server/latest/setup-and-upgrade/installation-requirements/server-host/\">details</a>]</p>\n<p>Set the PATH system variable: <a href=\"https://www.java.com/en/download/help/path.xml\">How do I set or change the PATH system variable?</a></p>\n<blockquote>\n<p>Note: In order to analyze JavaScript code, you need to have Node.js >= 8 installed on the machine running the scan. If a standard node is not available, you have to set the property <code>sonar.nodejs.executable</code> to an absolute path to Node.js executable. [<a href=\"https://docs.sonarqube.org/latest/analysis/languages/javascript/\">details</a>]</p>\n</blockquote>\n<h3 id=\"downloads-sonarqube-and-sonar-scanner\" style=\"position:relative;\"><a href=\"#downloads-sonarqube-and-sonar-scanner\" aria-label=\"downloads sonarqube and sonar scanner permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Downloads Sonarqube and Sonar Scanner:</h3>\n<ul>\n<li><a href=\"https://www.sonarqube.org/downloads\">LTS version of sonarqube</a></li>\n<li><a href=\"https://docs.sonarqube.org/latest/analysis/scan/sonarscanner/\">Download sonar-scanner</a> based on your platform\nAfter the above process, Add the sonar scanner path to environment variables.</li>\n</ul>\n<h3 id=\"run-sonarqube-server\" style=\"position:relative;\"><a href=\"#run-sonarqube-server\" aria-label=\"run sonarqube 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>Run Sonarqube server:</h3>\n<ul>\n<li>\n<p>To start the sonar server open cmd or terminal and set sonarqube bin folder path and choose the platform and run the following command. Examples :</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">#For Windows(cmd):</span>\n<span class=\"grvsc-line\">C:\\sonarqube\\bin\\windows-x86-64&gt;StartSonar.bat</span>\n<span class=\"grvsc-line\">#For other OS (terminal): </span>\n<span class=\"grvsc-line\">C:\\sonarqube\\bin\\[OS]&gt;sonar.sh</span></code></pre>\n<p>Once the sonar server up successfully, then Log in to <code>http://localhost:9000</code> with System Administrator credentials (login=admin, password=admin).</p>\n</li>\n</ul>\n<h3 id=\"creating-and-analysing-a-project\" style=\"position:relative;\"><a href=\"#creating-and-analysing-a-project\" aria-label=\"creating and analysing a 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>Creating and Analysing a Project:</h3>\n<ul>\n<li>Go to create a new project and enter the project key, and display name details. (+ sign on the top right side).</li>\n<li>Provide a token by either generating a token or using an existing token (find existing token on  <code>http://localhost:9000/account/security</code> page).</li>\n<li>Run analysis on the project by selecting the programming language used in the repository and your system OS. </li>\n<li>As we already downloaded and set up the sonar-scanner path, No need to download it again.</li>\n<li>\n<p>Now copy the displaying command and Go to your project path and Run the copied command. It looks like below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">sonar-scanner.bat -D&quot;sonar.projectKey=rtetre&quot; -D&quot;sonar.sources=.&quot;-D&quot;sonar.host.url=http://localhost:9000&quot; -D&quot;sonar.login=e932dxxxxx9a8e5c7903xxxxxx96928xxxxxxx&quot;</span></code></pre>\n</li>\n</ul>\n<p>After the analysis is done, you can either browse the provided link to see the sonar report directly [Ex.: <code>http://localhost:9000/dashboard?id=</code>] or go to the project section to see the newly generated sonar report of your project. </p>\n<p>If you want to exclude some files from analysis(like test files), then go to the administration section and navigate to the General setting, select the programming language used, and set a list of file path patterns to be excluded from the analysis.</p>\n<p>Now re-run the analysis command given above for an updated sonar report.</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>The goal of SonarQube is to empower developers first and to grow an open community around the quality and security of code. I hope with this quick tutorial of sonarqube you have the basic idea of the functionalities, and If you believe so, drop a comment and show your support.</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":"July 11, 2020","updated_date":null,"description":"SonarQube is a universal tool for static code analysis that has become more or less the industry standard. Keeping code clean, simple, and easy to read is also a lot easier with SonarQube.","title":"Sonarqube: What it is and why to use it?","tags":["Code Quality","SonarQube"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7699115044247788,"src":"/static/003f532e69e3da13ba2847a99744ade0/58556/sonarqube.webp","srcSet":"/static/003f532e69e3da13ba2847a99744ade0/61e93/sonarqube.webp 200w,\n/static/003f532e69e3da13ba2847a99744ade0/1f5c5/sonarqube.webp 400w,\n/static/003f532e69e3da13ba2847a99744ade0/58556/sonarqube.webp 800w,\n/static/003f532e69e3da13ba2847a99744ade0/99238/sonarqube.webp 1200w,\n/static/003f532e69e3da13ba2847a99744ade0/135cd/sonarqube.webp 1280w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Kheenvraj Lomror","github":"rajlomror","avatar":null}}}},{"node":{"excerpt":"In this blog, we’ll see how to create and validate a JWT(JSON Web Token) in Deno. For this, we’ll be using djwt, the absolute minimum…","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,"description":null,"title":"How to create and validate JSON Web Tokens in Deno","tags":["Deno","JWT","JSON Web Token"],"pinned":null,"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":{"excerpt":"Cloud Cost Optimization is the method of reducing the total cloud spending by finding mismanaged capital and scale-up of Right Sizing…","fields":{"slug":"/engineering/cloud-cost-optimization/"},"html":"<p>Cloud Cost Optimization is the method of reducing the total cloud spending by finding mismanaged capital and scale-up of Right Sizing computing services. CCO only charge for the services you use, the cloud gives companies infinite scalability and lower IT costs.</p>\n<ol>\n<li>As per Gartner <a href=\"https://www.gartner.com/smarterwithgartner/4-trends-impacting-cloud-adoption-in-2020/\">report</a> cloud cost optimization is the first factor that will impact cloud adoption in 2020. Also Gartner predicts <em>\"75% of midsize and large organizations will have adopted a multi-cloud and/or hybrid IT strategy in 2021.\"</em></li>\n<li>As <a href=\"https://research.g2.com/insights/2020-trends/it-cloud-computing-trends-2020\">per G2</a> <em>\"General necessity for a broad hardware stack will fade away as solutions become increasingly cloud-driven, virtualized, and software-defined. “Appliance-attached” solutions will decline in favor of dedicated, pure software solutions performing similar functions.</em></li>\n</ol>\n<h2 id=\"infrastructure-journey\" style=\"position:relative;\"><a href=\"#infrastructure-journey\" aria-label=\"infrastructure journey permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Infrastructure Journey</h2>\n<h3 id=\"on-premise\" style=\"position:relative;\"><a href=\"#on-premise\" aria-label=\"on premise permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>On-Premise</h3>\n<p>On-Premise Infrastructure was only option around 10 years ago but managing On-premise Infrastructure include the extra cost with other challenges, Challenges are Network, Hardware, Cooling, Power, Space also needed technical staff for taking care all infrastructure</p>\n<h3 id=\"colocation\" style=\"position:relative;\"><a href=\"#colocation\" aria-label=\"colocation permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Colocation</h3>\n<p>The Colocation is when a business places its own server in a third-party data center and uses its infrastructure services. Colocation takes responsibility for Network, Hardware, Cooling, Space also business not need to worry about technical man force for managing servers</p>\n<p>Still business have more challenges OS software, Application security, Data storage   </p>\n<h3 id=\"cloud\" style=\"position:relative;\"><a href=\"#cloud\" aria-label=\"cloud permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Cloud</h3>\n<p>The Cloud service provider is providing solutions for all the challenges. The cloud service provider takes total responsibility for hardware, network, space, power, maintaining, and security also they are managing all technical workforce for the whole infrastructure </p>\n<p>  <img src=\"/9475f7e05b9e351f919a2b693d2812da/infra1.webp\" alt=\"infra 1\"></p>\n<h2 id=\"how-to-reduce-cloud-cost\" style=\"position:relative;\"><a href=\"#how-to-reduce-cloud-cost\" aria-label=\"how to reduce cloud cost permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Reduce Cloud Cost</h2>\n<p>Reducing Cloud cost is not a one time task. it is a recurring process. We need to identify underutilized resources, Right size machine, reserving capacity for higher discounts also need to optimization Application for reducing hardware cost. Let's start </p>\n<h3 id=\"choose-the-right-cloud-provider\" style=\"position:relative;\"><a href=\"#choose-the-right-cloud-provider\" aria-label=\"choose the right cloud provider permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Choose the Right Cloud Provider</h3>\n<p>Cloud infrastructure is increasing day by day. Choosing the right cloud provider is the most important decision for long term success. The big three cloud providers are  Amazon Web Services (AWS), Microsoft Azure, and Google Cloud Platform (GCP). These three cloud providers are providing mostly services so they might be confused about choosing the right cloud provider. We can easily evaluate the right cloud provider from the following steps</p>\n<ul>\n<li>Compliance</li>\n<li>Security </li>\n<li>Downtime</li>\n<li>Support</li>\n<li>Pricing structure</li>\n<li>Location wise availability </li>\n</ul>\n<h3 id=\"discounted-instances\" style=\"position:relative;\"><a href=\"#discounted-instances\" aria-label=\"discounted instances permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Discounted Instances</h3>\n<p>All Big Cloud Providers are providing discounted Instances or spot instances. Spot instances are unused instances. Cloud Providers offered up to 90% discount on these instances compared to on-demand or reserved instances. The majority of organizations have some workloads that are not critical, We can reduce the cost for not critical workload by using spot instances. AWS, Azure, and Google (GCP) all provide the option to use Spot Instances.</p>\n<ul>\n<li>AWS Spot Instances </li>\n<li>Azure Low Priority VMS</li>\n<li>GCP Preemptible VMS</li>\n</ul>\n<h3 id=\"identify-instance-right-size\" style=\"position:relative;\"><a href=\"#identify-instance-right-size\" aria-label=\"identify instance right size permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Identify Instance Right Size</h3>\n<p>Identify the right size for the Instance, not an easy task. We need to configure multiple matrices in our cloud service provider. Key metrics to look for are CPU and memory usage. Identify instances with a maximum CPU usage and memory usage of the month.</p>\n<h2 id=\"how-to-check-metrics\" style=\"position:relative;\"><a href=\"#how-to-check-metrics\" aria-label=\"how to check metrics permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Check Metrics</h2>\n<p>Generally, people make mistakes during checking metrics. Most of the people prefer averages in monitoring but averages mislead the measurement. Let understand this by example </p>\n<p>You are running an online technology tutorial site. Suppose 1million active users on your website in normal days. Now you are hosting weekly technology webinars in your platform. During webinars time your platform traffic should increase. At that time CPU usages and memory usages should be high compared to the rest of the time. Now suppose you have checked the 24 hours average CPU usages and memory usages. It was around 40% and you have decided this is underutilized and scale down the lower size instance. It can impact you 5% - 10% traffic Let’s look at a real-world example. This chart shows the overall CPU usages </p>\n<p>  <img src=\"/205f2fae49dd4ac8281b545c5341d6ce/image1.webp\" alt=\"image 1\"></p>\n<p>First Image showing Average CPU utilization. You can see Maximum CPU was 18.6 %</p>\n<p>Now, let’s check the CPU 99th percentile:\n<img src=\"/6c898bdf0b5b329e83f2c089d0b71b28/image2.webp\" alt=\"image 2\"></p>\n<p>As expected, the 99th percentile is higher than the average. 99th percentile is around 93% </p>\n<p>The conclusion is We need to always check the 99th percentile. The average can mislead and it can impact your users.</p>\n<h3 id=\"creating-underutilization-alarm\" style=\"position:relative;\"><a href=\"#creating-underutilization-alarm\" aria-label=\"creating underutilization alarm permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Underutilization Alarm</h3>\n<p>We can create different types of resources and applications utilization monitoring matrix and based on the data we can configure multiple alarms. You can configure notification or alarms on email, SMS from the Cloud provider dashboard. you can also configure alarms that automatically stop or terminate EC2 instances or VM when instance unused or underutilized according to the configured threshold. During the development or some POC as a developer or devops person we have to create some instances or resources but sometimes we forgot to terminate the instances or resources. You can minimize the this extra cost by creating a group of alarms that sends an email notification to developers whose instances have been underutilized or ideal for some hours, then terminates an instance. It will save the overall infra cost. different cloud providers provide different ways for creating these type alarms</p>\n<ul>\n<li><a href=\"https://aws.amazon.com/cloudwatch/features/\">Amazone (Aws)</a></li>\n<li><a href=\"https://azure.microsoft.com/en-in/blog/announcing-azure-advisor-azure-monitor-and-resource-health/\">Azure</a> </li>\n<li><a href=\"https://cloud.google.com/compute/docs/instances/viewing-and-applying-idle-vm-recommendations\">Google Cloud</a></li>\n</ul>\n<h3 id=\"creating-time-based--actions\" style=\"position:relative;\"><a href=\"#creating-time-based--actions\" aria-label=\"creating time based  actions permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Creating time based  actions</h3>\n<p>You can save around 75% cost for your Non - Production Development, Staging, and QA environment. Non - Production environment generally needed during working days. You can turn off these servers during off-hours. Cost-saving depends on the infrastructure size, it can be hundred, thousands of dollars</p>\n<p>You can create automation scripts for infrastructure deployment. Schedule the script in your cloud provider         </p>\n<h3 id=\"in-memory-cache-storage\" style=\"position:relative;\"><a href=\"#in-memory-cache-storage\" aria-label=\"in memory cache 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>In-memory cache Storage</h3>\n<p>Application in-memory cache reduces the cost of transferring data in the network and overall application performance because reduce the traffic between the database servers or any other external application reduce the network level cost in the cloud also caching improves  the efficiency and accessibility of data that used repeatedly or frequently accessed. Suppose your application is fetching user configuration or settings in every request from the database server. You can keep this type of configuration, which is not changing frequently in the in-memory cache. it will save a lot network-level cost </p>\n<h3 id=\"data-transfer-cost-optimization\" style=\"position:relative;\"><a href=\"#data-transfer-cost-optimization\" aria-label=\"data transfer cost optimization permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Transfer Cost Optimization</h3>\n<p>Data Transfer cost mostly hidden or Some time we don't take care of it. Generally, data transfer is free in the same region between different services Storage, Compute service, etc.\nIf you do a lot of cross-region transfer, it will increase your network data transfer cost also if you will deploy multiple services in the same region it will improve application performance </p>\n<h3 id=\"cost-visibility\" style=\"position:relative;\"><a href=\"#cost-visibility\" aria-label=\"cost visibility permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Cost visibility</h3>\n<p>This includes knowing what you spend in detail, how specific services are billed, and the ability to display how (or why) you spent a specific amount Here, keep in mind key capabilities such as the ability to create shared accountability, hold frequent cost reviews, analyze trends, and visualize the impact of your actions on a near-real-time basis. You can also use cost controls like budget alerts and quotas to keep your costs in check over time. </p>\n<h3 id=\"consider-a-multi-cloud-architecture\" style=\"position:relative;\"><a href=\"#consider-a-multi-cloud-architecture\" aria-label=\"consider a multi cloud architecture permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Consider a Multi-Cloud Architecture</h3>\n<p>Enterprises or Mid Level companies are adopting multi-cloud infrastructure. Consider this recent prediction from IDC: “By 2020, over 90% of enterprises will use multiple cloud services and platforms.” Or this one from 451 Research: “The future of IT is multi-cloud and hybrid with 69% of respondents planning to have some type of multi-cloud environment by 2019.”  </p>\n<h3 id=\"benefits-of-multi-cloud-architecture\" style=\"position:relative;\"><a href=\"#benefits-of-multi-cloud-architecture\" aria-label=\"benefits of multi cloud architecture permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Benefits of multi-cloud Architecture</h3>\n<ul>\n<li>Low latency</li>\n<li>Competitive Pricing</li>\n<li>more compliance options</li>\n<li>Enhanced Security </li>\n</ul>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>Organizations need to develop a cost optimization culture and awareness. Cost optimization is an ongoing activity in the organization. Need to decide someone responsible for the cost optimization it can be an Engineering team or DevOps team. Most cloud providers provide billing alarm’s they can alert you in case of cost increment also we can configure budget in the Cloud provider dashboard.</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":"July 09, 2020","updated_date":null,"description":"Optimization of cloud costs lowers spending by recognizing mismanaged capital, reserving higher discount space, and proper sizing.","title":"Cloud Cost Optimization in 2021","tags":["Cloud","Optmization"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.408450704225352,"src":"/static/9b95fca99dc1c53ce661e89fd0341f6d/58556/cloud.webp","srcSet":"/static/9b95fca99dc1c53ce661e89fd0341f6d/61e93/cloud.webp 200w,\n/static/9b95fca99dc1c53ce661e89fd0341f6d/1f5c5/cloud.webp 400w,\n/static/9b95fca99dc1c53ce661e89fd0341f6d/58556/cloud.webp 800w,\n/static/9b95fca99dc1c53ce661e89fd0341f6d/99238/cloud.webp 1200w,\n/static/9b95fca99dc1c53ce661e89fd0341f6d/7c22d/cloud.webp 1600w,\n/static/9b95fca99dc1c53ce661e89fd0341f6d/8dda0/cloud.webp 1747w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Vijay Singh Shekhawat","github":"code-vj","avatar":null}}}},{"node":{"excerpt":"This post will cover a demo working setup of a service mesh architecture using Envoy using a demo application. In this service mesh…","fields":{"slug":"/engineering/service-mesh-with-envoy/"},"html":"<p>This post will cover a demo working setup of a service mesh architecture using Envoy using a demo application. In this service mesh architecture, we will be using Envoy proxy for both control and data plane. The setup is deployed in a Kubernetes cluster using Amazon EKS.</p>\n<h1 id=\"pre-requisites\" style=\"position:relative;\"><a href=\"#pre-requisites\" aria-label=\"pre requisites permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Pre-requisites</h1>\n<p>We will be deploying an echo-grpc test application provided by Google in their article related to gRPC load balancing and was used as a reference to test the service mesh setup with Envoy. The article covers setting up Envoy as an edge proxy only.\nThis is a simple gRPC application that exposes a unary method that takes a string in the content request field and responds with the content unaltered.\nRepo: <a href=\"https://github.com/GoogleCloudPlatform/grpc-gke-nlb-tutorial\">grpc-gke-nlb-tutorial</a></p>\n<ul>\n<li>Clone this repo.</li>\n<li>Go to the echo-grpc directory.</li>\n<li>Using the Dockerfile provided in the folder, we would have to build the image and push it to the Docker registry of choice. Since we are not using GCP, Docker Hub is used as the registry.</li>\n<li>Run docker login and login with your hub credentials.</li>\n<li>Build the image docker build -t echo-grpc .</li>\n<li>Tag the image docker tag echo-grpc <hub-username>/echo-grpc</li>\n<li>Push the image docker push <hub-username>/echo-grpc</li>\n<li>Create a separate folder to put all the YAML files.</li>\n<li>Create namespace in k8s:\n<code>kubectl create namespace envoy</code></li>\n<li>Install grpcurl tool which is similar to curl but for gRPC for testing:\n<code>go get github.com/fullstorydev/grpcurl</code></li>\n</ul>\n<h1 id=\"sidecar-deployment\" style=\"position:relative;\"><a href=\"#sidecar-deployment\" aria-label=\"sidecar deployment permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Sidecar Deployment</h1>\n<p>Configuration of envoy for the sidecar deployment:</p>\n<p><strong>envoy-echo.yaml:</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">apiVersion: v1</span>\n<span class=\"grvsc-line\">kind: ConfigMap</span>\n<span class=\"grvsc-line\">metadata:</span>\n<span class=\"grvsc-line\">  name: envoy-echo</span>\n<span class=\"grvsc-line\">data:</span>\n<span class=\"grvsc-line\">  envoy.yaml: |</span>\n<span class=\"grvsc-line\">    static_resources:</span>\n<span class=\"grvsc-line\">      listeners:</span>\n<span class=\"grvsc-line\">      - address:</span>\n<span class=\"grvsc-line\">          socket_address:</span>\n<span class=\"grvsc-line\">            address: 0.0.0.0</span>\n<span class=\"grvsc-line\">            port_value: 8786</span>\n<span class=\"grvsc-line\">        filter_chains:</span>\n<span class=\"grvsc-line\">        - filters:</span>\n<span class=\"grvsc-line\">          - name: envoy.http_connection_manager</span>\n<span class=\"grvsc-line\">            config:</span>\n<span class=\"grvsc-line\">              access_log:</span>\n<span class=\"grvsc-line\">              - name: envoy.file_access_log</span>\n<span class=\"grvsc-line\">                config:</span>\n<span class=\"grvsc-line\">                  path: &quot;/dev/stdout&quot;</span>\n<span class=\"grvsc-line\">              codec_type: AUTO</span>\n<span class=\"grvsc-line\">              stat_prefix: ingress_https</span>\n<span class=\"grvsc-line\">              route_config:</span>\n<span class=\"grvsc-line\">                name: local_route</span>\n<span class=\"grvsc-line\">                virtual_hosts:</span>\n<span class=\"grvsc-line\">                - name: https</span>\n<span class=\"grvsc-line\">                  domains:</span>\n<span class=\"grvsc-line\">                  - &quot;*&quot;</span>\n<span class=\"grvsc-line\">                  routes:</span>\n<span class=\"grvsc-line\">                  - match:</span>\n<span class=\"grvsc-line\">                      prefix: &quot;/api.Echo/&quot;</span>\n<span class=\"grvsc-line\">                    route:</span>\n<span class=\"grvsc-line\">                      cluster: echo-grpc</span>\n<span class=\"grvsc-line\">              http_filters:</span>\n<span class=\"grvsc-line\">              - name: envoy.health_check</span>\n<span class=\"grvsc-line\">                config:</span>\n<span class=\"grvsc-line\">                  pass_through_mode: false</span>\n<span class=\"grvsc-line\">                  headers:</span>\n<span class=\"grvsc-line\">                  - name: &quot;:path&quot;</span>\n<span class=\"grvsc-line\">                    exact_match: &quot;/healthz&quot;</span>\n<span class=\"grvsc-line\">                  - name: &quot;x-envoy-livenessprobe&quot;</span>\n<span class=\"grvsc-line\">                    exact_match: &quot;healthz&quot;</span>\n<span class=\"grvsc-line\">              - name: envoy.router</span>\n<span class=\"grvsc-line\">                config: {}</span>\n<span class=\"grvsc-line\">      clusters:</span>\n<span class=\"grvsc-line\">      - name: echo-grpc</span>\n<span class=\"grvsc-line\">        connect_timeout: 0.5s</span>\n<span class=\"grvsc-line\">        type: STATIC</span>\n<span class=\"grvsc-line\">        lb_policy: ROUND_ROBIN</span>\n<span class=\"grvsc-line\">        http2_protocol_options: {}</span>\n<span class=\"grvsc-line\">        load_assignment:</span>\n<span class=\"grvsc-line\">          cluster_name: echo-grpc</span>\n<span class=\"grvsc-line\">          endpoints:</span>\n<span class=\"grvsc-line\">          - lb_endpoints:</span>\n<span class=\"grvsc-line\">            - endpoint:</span>\n<span class=\"grvsc-line\">                address:</span>\n<span class=\"grvsc-line\">                  socket_address:</span>\n<span class=\"grvsc-line\">                    address: &quot;127.0.0.1&quot;</span>\n<span class=\"grvsc-line\">                    port_value: 8081</span>\n<span class=\"grvsc-line\">        health_checks:</span>\n<span class=\"grvsc-line\">          timeout: 1s</span>\n<span class=\"grvsc-line\">          interval: 10s</span>\n<span class=\"grvsc-line\">          unhealthy_threshold: 2</span>\n<span class=\"grvsc-line\">          healthy_threshold: 2</span>\n<span class=\"grvsc-line\">          grpc_health_check: {}</span>\n<span class=\"grvsc-line\">    admin:</span>\n<span class=\"grvsc-line\">      access_log_path: &quot;/dev/stdout&quot;</span>\n<span class=\"grvsc-line\">      address:</span>\n<span class=\"grvsc-line\">        socket_address:</span>\n<span class=\"grvsc-line\">          address: 127.0.0.1</span>\n<span class=\"grvsc-line\">          port_value: 8090</span></code></pre>\n<p>A couple things to note here. </p>\n<ul>\n<li>We are exposing sidecar on 8786 port on the container. </li>\n<li>Filter <strong>envoy.http<em>connection</em>manager</strong> handles the HTTP traffic. </li>\n<li><strong>route_config</strong> is used to define the routes for each domain to their respective clusters. Here we are keeping the domain as <code>*</code>, allowing all domains to pass-through.</li>\n<li>A cluster is envoy defines the services that will be called based on the route.</li>\n<li>In the cluster, the <strong>lb_policy</strong> defines the algorithm for load balancing, keeping as ROUND<em>ROBIN, with type STATIC because it is a sidecar and needs to communicate to only one pod always which leads to the reason for keeping the address in socket</em>address as localhost while port_value is what will be exposed by that particular service’s deployment.</li>\n</ul>\n<p>Run:\n<code>kubectl apply -f envoy-echo.yaml -n envoy</code></p>\n<p>Deployment of echo-grpc application with 3 replicas. The config contains two containers, one for application and another being the Envoy image.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">apiVersion: apps/v1</span>\n<span class=\"grvsc-line\">kind: Deployment</span>\n<span class=\"grvsc-line\">metadata:</span>\n<span class=\"grvsc-line\">  name: echo-grpc</span>\n<span class=\"grvsc-line\">spec:</span>\n<span class=\"grvsc-line\">  replicas: 3</span>\n<span class=\"grvsc-line\">  selector:</span>\n<span class=\"grvsc-line\">    matchLabels:</span>\n<span class=\"grvsc-line\">      app: echo-grpc</span>\n<span class=\"grvsc-line\">  template:</span>\n<span class=\"grvsc-line\">    metadata:</span>\n<span class=\"grvsc-line\">      labels:</span>\n<span class=\"grvsc-line\">        app: echo-grpc</span>\n<span class=\"grvsc-line\">    spec:</span>\n<span class=\"grvsc-line\">      containers:</span>\n<span class=\"grvsc-line\">      - name: echo-grpc</span>\n<span class=\"grvsc-line\">        image: &lt;hub-username&gt;/echo-grpc</span>\n<span class=\"grvsc-line\">        imagePullPolicy: Always</span>\n<span class=\"grvsc-line\">        resources: {}</span>\n<span class=\"grvsc-line\">        env:</span>\n<span class=\"grvsc-line\">        - name: &quot;PORT&quot;</span>\n<span class=\"grvsc-line\">          value: &quot;8081&quot;</span>\n<span class=\"grvsc-line\">        ports:</span>\n<span class=\"grvsc-line\">        - containerPort: 8081</span>\n<span class=\"grvsc-line\">        readinessProbe:</span>\n<span class=\"grvsc-line\">          exec:</span>\n<span class=\"grvsc-line\">            command: [&quot;/bin/grpc_health_probe&quot;, &quot;-addr=:8081&quot;]</span>\n<span class=\"grvsc-line\">          initialDelaySeconds: 1</span>\n<span class=\"grvsc-line\">        livenessProbe:</span>\n<span class=\"grvsc-line\">          exec:</span>\n<span class=\"grvsc-line\">            command: [&quot;/bin/grpc_health_probe&quot;, &quot;-addr=:8081&quot;]</span>\n<span class=\"grvsc-line\">          initialDelaySeconds: 1</span>\n<span class=\"grvsc-line\">      - name: envoy</span>\n<span class=\"grvsc-line\">        image: envoyproxy/envoy:v1.9.1</span>\n<span class=\"grvsc-line\">        resources: {}</span>\n<span class=\"grvsc-line\">        ports:</span>\n<span class=\"grvsc-line\">        - name: https</span>\n<span class=\"grvsc-line\">          containerPort: 443</span>\n<span class=\"grvsc-line\">        volumeMounts:</span>\n<span class=\"grvsc-line\">        - name: config</span>\n<span class=\"grvsc-line\">          mountPath: /etc/envoy</span>\n<span class=\"grvsc-line\">      volumes:</span>\n<span class=\"grvsc-line\">        - name: config</span>\n<span class=\"grvsc-line\">          configMap:</span>\n<span class=\"grvsc-line\">            name: envoy-echo</span></code></pre>\n<p>Here, echo-grpc is test application and envoy is being deployed in the same pod. Config volumes are mounted so that the envoy can read the configmaps.</p>\n<p>Run:\n<code>kubectl apply -f echo-deployment.yaml -n envoy</code></p>\n<h1 id=\"headless-service-configuration\" style=\"position:relative;\"><a href=\"#headless-service-configuration\" aria-label=\"headless service configuration permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Headless Service Configuration</h1>\n<p>We are using headless service for echo-grpc. Using service as headless will expose the Pods IP to the DNS server of kubernetes which will be used by Envoy to do service discovery for the pods.</p>\n<p><strong>echo-service.yaml</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">apiVersion: v1</span>\n<span class=\"grvsc-line\">kind: Service</span>\n<span class=\"grvsc-line\">metadata:</span>\n<span class=\"grvsc-line\">  name: echo-grpc</span>\n<span class=\"grvsc-line\">spec:</span>\n<span class=\"grvsc-line\">  type: ClusterIP</span>\n<span class=\"grvsc-line\">  clusterIP: None</span>\n<span class=\"grvsc-line\">  selector:</span>\n<span class=\"grvsc-line\">    app: echo-grpc</span>\n<span class=\"grvsc-line\">  ports:</span>\n<span class=\"grvsc-line\">  - name: http2-echo</span>\n<span class=\"grvsc-line\">    protocol: TCP</span>\n<span class=\"grvsc-line\">    port: 8786</span>\n<span class=\"grvsc-line\">  - name: http2-service</span>\n<span class=\"grvsc-line\">    protocol: TCP</span>\n<span class=\"grvsc-line\">    port: 8081</span></code></pre>\n<p>In the above config file, we are exposing two ports, one for envoy sidecar (this is the same port we mentioned in the config map of sidecar envoy) and one for the service itself.</p>\n<p>Run:\n<code>kubectl apply -f echo-service.yaml -n envoy</code></p>\n<h1 id=\"front-envoy-configuration\" style=\"position:relative;\"><a href=\"#front-envoy-configuration\" aria-label=\"front envoy configuration permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Front Envoy Configuration</h1>\n<p>Creating a service of type LoadBalancer so that client can access the backend service.</p>\n<p><strong>envoy-service.yaml:</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">apiVersion: v1</span>\n<span class=\"grvsc-line\">kind: Service</span>\n<span class=\"grvsc-line\">metadata:</span>\n<span class=\"grvsc-line\">  name: envoy</span>\n<span class=\"grvsc-line\">spec:</span>\n<span class=\"grvsc-line\">  type: LoadBalancer</span>\n<span class=\"grvsc-line\">  selector:</span>\n<span class=\"grvsc-line\">    app: envoy</span>\n<span class=\"grvsc-line\">  ports:</span>\n<span class=\"grvsc-line\">  - name: https</span>\n<span class=\"grvsc-line\">    protocol: TCP</span>\n<span class=\"grvsc-line\">    port: 443</span>\n<span class=\"grvsc-line\">    targetPort: 443</span></code></pre>\n<h3 id=\"creating-self-signed-certificates\" style=\"position:relative;\"><a href=\"#creating-self-signed-certificates\" aria-label=\"creating self signed certificates permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 self-signed certificates</h3>\n<p>Run:\n<code>kubectl apply -f envoy-service.yaml -n envoy</code></p>\n<p>Since we are deploying front envoy LoadBalancer on port 443, we have to create a self-signed certificate to make it terminate SSL/TLS connection.</p>\n<ul>\n<li>Get the external IP:\n<code>kubectl describe svc/envoy -n envoy</code></li>\n<li>Copy the LoadBalancer address in the EXTERNAL-IP section and do a nslookup and copy the IP address:\n<code>nslookup &#x3C;your load balancer aadess></code></li>\n<li>Create a self-signed cert and key:\n<code>openssl req -x509 -nodes -newkey rsa:2048 -days 365 -keyout privkey.pem -out cert.pem -subj \"/CN=&#x3C;ip-address>\"</code></li>\n<li>Create a Kubernetes TLS Secret called envoy-certs that contains the self-signed SSL/TLS certificate and key:\n<code>kubectl create secret tls envoy-certs --key privkey.pem --cert cert.pem --dry-run -o yaml</code></li>\n</ul>\n<h3 id=\"edge-envoy-configuration\" style=\"position:relative;\"><a href=\"#edge-envoy-configuration\" aria-label=\"edge envoy configuration permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Edge Envoy configuration</h3>\n<p>Configuration for the edge Envoy:</p>\n<p><strong>envoy-configmap.yaml</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">apiVersion: v1</span>\n<span class=\"grvsc-line\">kind: ConfigMap</span>\n<span class=\"grvsc-line\">metadata:</span>\n<span class=\"grvsc-line\">  name: envoy-conf</span>\n<span class=\"grvsc-line\">data:</span>\n<span class=\"grvsc-line\">  envoy.yaml: |</span>\n<span class=\"grvsc-line\">    static_resources:</span>\n<span class=\"grvsc-line\">      listeners:</span>\n<span class=\"grvsc-line\">      - address:</span>\n<span class=\"grvsc-line\">          socket_address:</span>\n<span class=\"grvsc-line\">            address: 0.0.0.0</span>\n<span class=\"grvsc-line\">            port_value: 443</span>\n<span class=\"grvsc-line\">        filter_chains:</span>\n<span class=\"grvsc-line\">        - filters:</span>\n<span class=\"grvsc-line\">          - name: envoy.http_connection_manager</span>\n<span class=\"grvsc-line\">            config:</span>\n<span class=\"grvsc-line\">              access_log:</span>\n<span class=\"grvsc-line\">              - name: envoy.file_access_log</span>\n<span class=\"grvsc-line\">                config:</span>\n<span class=\"grvsc-line\">                  path: &quot;/dev/stdout&quot;</span>\n<span class=\"grvsc-line\">              codec_type: AUTO</span>\n<span class=\"grvsc-line\">              stat_prefix: ingress_https</span>\n<span class=\"grvsc-line\">              route_config:</span>\n<span class=\"grvsc-line\">                name: local_route</span>\n<span class=\"grvsc-line\">                virtual_hosts:</span>\n<span class=\"grvsc-line\">                - name: https</span>\n<span class=\"grvsc-line\">                  domains:</span>\n<span class=\"grvsc-line\">                  - &quot;*&quot;</span>\n<span class=\"grvsc-line\">                  routes:</span>\n<span class=\"grvsc-line\">                  - match:</span>\n<span class=\"grvsc-line\">                      prefix: &quot;/api.Echo/&quot;</span>\n<span class=\"grvsc-line\">                    route:</span>\n<span class=\"grvsc-line\">                      cluster: echo-grpc</span>\n<span class=\"grvsc-line\">              http_filters:</span>\n<span class=\"grvsc-line\">              - name: envoy.health_check</span>\n<span class=\"grvsc-line\">                config:</span>\n<span class=\"grvsc-line\">                  pass_through_mode: false</span>\n<span class=\"grvsc-line\">                  headers:</span>\n<span class=\"grvsc-line\">                  - name: &quot;:path&quot;</span>\n<span class=\"grvsc-line\">                    exact_match: &quot;/healthz&quot;</span>\n<span class=\"grvsc-line\">                  - name: &quot;x-envoy-livenessprobe&quot;</span>\n<span class=\"grvsc-line\">                    exact_match: &quot;healthz&quot;</span>\n<span class=\"grvsc-line\">              - name: envoy.router</span>\n<span class=\"grvsc-line\">                config: {}</span>\n<span class=\"grvsc-line\">          tls_context:</span>\n<span class=\"grvsc-line\">            common_tls_context:</span>\n<span class=\"grvsc-line\">              tls_certificates:</span>\n<span class=\"grvsc-line\">              - certificate_chain:</span>\n<span class=\"grvsc-line\">                  filename: &quot;/etc/ssl/envoy/tls.crt&quot;</span>\n<span class=\"grvsc-line\">                private_key:</span>\n<span class=\"grvsc-line\">                  filename: &quot;/etc/ssl/envoy/tls.key&quot;</span>\n<span class=\"grvsc-line\">      clusters:</span>\n<span class=\"grvsc-line\">      - name: echo-grpc</span>\n<span class=\"grvsc-line\">        connect_timeout: 0.5s</span>\n<span class=\"grvsc-line\">        type: STRICT_DNS</span>\n<span class=\"grvsc-line\">        lb_policy: ROUND_ROBIN</span>\n<span class=\"grvsc-line\">        http2_protocol_options: {}</span>\n<span class=\"grvsc-line\">        load_assignment:</span>\n<span class=\"grvsc-line\">          cluster_name: echo-grpc</span>\n<span class=\"grvsc-line\">          endpoints:</span>\n<span class=\"grvsc-line\">          - lb_endpoints:</span>\n<span class=\"grvsc-line\">            - endpoint:</span>\n<span class=\"grvsc-line\">                address:</span>\n<span class=\"grvsc-line\">                  socket_address:</span>\n<span class=\"grvsc-line\">                    address: echo-grpc.envoy.svc.cluster.local</span>\n<span class=\"grvsc-line\">                    port_value: 8786</span>\n<span class=\"grvsc-line\">        health_checks:</span>\n<span class=\"grvsc-line\">          timeout: 1s</span>\n<span class=\"grvsc-line\">          interval: 10s</span>\n<span class=\"grvsc-line\">          unhealthy_threshold: 2</span>\n<span class=\"grvsc-line\">          healthy_threshold: 2</span>\n<span class=\"grvsc-line\">          grpc_health_check: {}</span>\n<span class=\"grvsc-line\">    admin:</span>\n<span class=\"grvsc-line\">      access_log_path: &quot;/dev/stdout&quot;</span>\n<span class=\"grvsc-line\">      address:</span>\n<span class=\"grvsc-line\">        socket_address:</span>\n<span class=\"grvsc-line\">          address: 127.0.0.1</span>\n<span class=\"grvsc-line\">          port_value: 8090</span></code></pre>\n<p>Since we will be offloading HTTPS, we are using port_value of 443. Most of the configurations are same as of sidecar envoy except for three things:</p>\n<ul>\n<li>A <strong>tls_context</strong> config is required to mention the tls certifications needed for authentication purposes.</li>\n<li>In clusters, the type has been to STATIC to STRICT_DNS which is a kind of service discovery mechanism making use of Headless service we deployed earlier.</li>\n<li>The socket_address’s address value has been changed to the FQDN of the service.</li>\n</ul>\n<p>Run:\n<code>kubectl apply -f envoy-configmap.yaml -n envoy</code></p>\n<h3 id=\"deployment-configuration\" style=\"position:relative;\"><a href=\"#deployment-configuration\" aria-label=\"deployment configuration permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Deployment Configuration</h3>\n<p><strong>envoy-deployment.yaml</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">apiVersion: apps/v1</span>\n<span class=\"grvsc-line\">kind: Deployment</span>\n<span class=\"grvsc-line\">metadata:</span>\n<span class=\"grvsc-line\">  name: envoy</span>\n<span class=\"grvsc-line\">spec:</span>\n<span class=\"grvsc-line\">  replicas: 2</span>\n<span class=\"grvsc-line\">  selector:</span>\n<span class=\"grvsc-line\">    matchLabels:</span>\n<span class=\"grvsc-line\">      app: envoy</span>\n<span class=\"grvsc-line\">  template:</span>\n<span class=\"grvsc-line\">    metadata:</span>\n<span class=\"grvsc-line\">      labels:</span>\n<span class=\"grvsc-line\">        app: envoy</span>\n<span class=\"grvsc-line\">    spec:</span>\n<span class=\"grvsc-line\">      containers:</span>\n<span class=\"grvsc-line\">      - name: envoy</span>\n<span class=\"grvsc-line\">        image: envoyproxy/envoy:v1.9.1</span>\n<span class=\"grvsc-line\">        resources: {}</span>\n<span class=\"grvsc-line\">        ports:</span>\n<span class=\"grvsc-line\">        - name: https</span>\n<span class=\"grvsc-line\">          containerPort: 443</span>\n<span class=\"grvsc-line\">        volumeMounts:</span>\n<span class=\"grvsc-line\">        - name: config</span>\n<span class=\"grvsc-line\">          mountPath: /etc/envoy</span>\n<span class=\"grvsc-line\">        - name: certs</span>\n<span class=\"grvsc-line\">          mountPath: /etc/ssl/envoy</span>\n<span class=\"grvsc-line\">        readinessProbe:</span>\n<span class=\"grvsc-line\">          httpGet:</span>\n<span class=\"grvsc-line\">            scheme: HTTPS</span>\n<span class=\"grvsc-line\">            path: /healthz</span>\n<span class=\"grvsc-line\">            httpHeaders:</span>\n<span class=\"grvsc-line\">            - name: x-envoy-livenessprobe</span>\n<span class=\"grvsc-line\">              value: healthz</span>\n<span class=\"grvsc-line\">            port: 443</span>\n<span class=\"grvsc-line\">          initialDelaySeconds: 3</span>\n<span class=\"grvsc-line\">        livenessProbe:</span>\n<span class=\"grvsc-line\">          httpGet:</span>\n<span class=\"grvsc-line\">            scheme: HTTPS</span>\n<span class=\"grvsc-line\">            path: /healthz</span>\n<span class=\"grvsc-line\">            httpHeaders:</span>\n<span class=\"grvsc-line\">            - name: x-envoy-livenessprobe</span>\n<span class=\"grvsc-line\">              value: healthz</span>\n<span class=\"grvsc-line\">            port: 443</span>\n<span class=\"grvsc-line\">          initialDelaySeconds: 10</span>\n<span class=\"grvsc-line\">      volumes:</span>\n<span class=\"grvsc-line\">      - name: config</span>\n<span class=\"grvsc-line\">        configMap:</span>\n<span class=\"grvsc-line\">          name: envoy-conf</span>\n<span class=\"grvsc-line\">      - name: certs</span>\n<span class=\"grvsc-line\">        secret:</span>\n<span class=\"grvsc-line\">          secretName: envoy-certs</span></code></pre>\n<p>Run:\n<code>kubectl apply -f envoy-deployment.yaml -n envoy</code></p>\n<h1 id=\"testing\" style=\"position:relative;\"><a href=\"#testing\" aria-label=\"testing permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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</h1>\n<p>Proto file for the echo-grpc service:</p>\n<p><strong>ccho.proto:</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">syntax = &quot;proto3&quot;;</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">package api;</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">service Echo {</span>\n<span class=\"grvsc-line\">  rpc Echo (EchoRequest) returns (EchoResponse) {}</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">message EchoRequest {</span>\n<span class=\"grvsc-line\">  string content = 1;</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">message EchoResponse {</span>\n<span class=\"grvsc-line\">  string content = 1;</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<p>Run the following command to call the server:\n<code>grpcurl -d '{\"content\": \"echo\"}' -proto echo.proto -insecure -v &#x3C;load_balancer_or_external_ip>:443 api.Echo/Echo</code></p>\n<p>The output will be similar to something like this:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">Resolved method descriptor:</span>\n<span class=\"grvsc-line\">rpc Echo ( .api.EchoRequest ) returns ( .api.EchoResponse );</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">Request metadata to send:</span>\n<span class=\"grvsc-line\">(empty)</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">Response headers received:</span>\n<span class=\"grvsc-line\">content-type: application/grpc</span>\n<span class=\"grvsc-line\">date: Wed, 27 Feb 2019 04:40:19 GMT</span>\n<span class=\"grvsc-line\">hostname: echo-grpc-5c4f59c578-wcsvr</span>\n<span class=\"grvsc-line\">server: envoy</span>\n<span class=\"grvsc-line\">x-envoy-upstream-service-time: 0</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">Response contents:</span>\n<span class=\"grvsc-line\">{</span>\n<span class=\"grvsc-line\">  &quot;content&quot;: &quot;echo&quot;</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">Response trailers received:</span>\n<span class=\"grvsc-line\">(empty)</span>\n<span class=\"grvsc-line\">Sent 1 request and received 1 response</span></code></pre>\n<p>Run the above command multiple times and check the value of the hostname field every time which will contain the pod name of one of the 3 pods deployed. </p>\n<h1 id=\"references\" style=\"position:relative;\"><a href=\"#references\" aria-label=\"references permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>References</h1>\n<ul>\n<li>Article: <a href=\"https://cloud.google.com/solutions/exposing-grpc-services-on-gke-using-envoy-proxy\">Using Envoy Proxy to load-balance gRPC services on GKE</a></li>\n<li><a href=\"https://kubernetes.io/docs/concepts/services-networking/service/#headless-services\">Headless service</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</style>","frontmatter":{"date":"July 06, 2020","updated_date":null,"description":null,"title":"Service Mesh with Envoy","tags":["Service Mesh","Envoy","Microservices"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.834862385321101,"src":"/static/150ba7965ba96274595177480a3f562a/58556/front-image.webp","srcSet":"/static/150ba7965ba96274595177480a3f562a/61e93/front-image.webp 200w,\n/static/150ba7965ba96274595177480a3f562a/1f5c5/front-image.webp 400w,\n/static/150ba7965ba96274595177480a3f562a/58556/front-image.webp 800w,\n/static/150ba7965ba96274595177480a3f562a/99238/front-image.webp 1200w,\n/static/150ba7965ba96274595177480a3f562a/7c22d/front-image.webp 1600w,\n/static/150ba7965ba96274595177480a3f562a/90b9d/front-image.webp 2100w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Piyush Kumar","github":"kpiyush17","avatar":null}}}},{"node":{"excerpt":"Kafka Streams is a Java library developed to help applications that do stream processing built on Kafka. To learn about Kafka Streams, you…","fields":{"slug":"/engineering/stream-processing-using-kafka/"},"html":"<p>Kafka Streams is a Java library developed to help applications that do stream processing built on Kafka. To learn about Kafka Streams, you need to have a basic idea about Kafka to understand better.  If you’ve worked with Kafka before, Kafka Streams is going to be easy to understand.</p>\n<h2 id=\"what-are-kafka-streams\" style=\"position:relative;\"><a href=\"#what-are-kafka-streams\" aria-label=\"what are kafka streams permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What are Kafka Streams?</h2>\n<p>Kafka Streams is a streaming application building library, specifically applications that turn Kafka input topics into Kafka output topics. Kafka Streams enables you to do this in a way that is distributed and fault-tolerant, with succinct code.</p>\n<h2 id=\"what-is-stream-processing\" style=\"position:relative;\"><a href=\"#what-is-stream-processing\" aria-label=\"what is stream processing permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Stream processing?</h2>\n<p>Stream processing is the ongoing, concurrent, and record-by-record real-time processing of data.</p>\n<p><strong>Let us get started with some highlights of Kafka Streams:</strong></p>\n<ul>\n<li>Low Barrier to Entry:  Quickly write and run a small-scale POC on a single instance. You only need to run multiple instances of the application on various machines to scale up to high-volume production workloads.</li>\n<li>Lightweight and straightforward client library:  Can be easily embedded in any Java application and integrated with any existing packaging, deployment, and operational tools.</li>\n<li>No external dependencies on systems other than <a href=\"https://en.wikipedia.org/wiki/Apache_Kafka\">Apache Kafka</a> itself</li>\n<li>Fault-tolerant local state: Enables fast and efficient stateful operations like windowed joins and aggregations</li>\n<li>Supports exactly-once processing: Each record will be processed once and only once, even when there is a failure.</li>\n<li>One-record-at-a-time processing to achieve millisecond processing latency supports event-time-based windowing operations with out-of-order arrival of records.</li>\n</ul>\n<h2 id=\"kafka-streams-concepts\" style=\"position:relative;\"><a href=\"#kafka-streams-concepts\" aria-label=\"kafka streams concepts permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Kafka Streams Concepts:</h2>\n<ul>\n<li><strong>Stream</strong>:  An ordered, replayable, and fault-tolerant sequence of immutable data records, where each data record is defined as a key-value pair.</li>\n<li><strong>Stream Processor</strong>:  A node in the processor topology represents a processing step to transform data in streams by receiving one input record at a time from its source in the topology, applying any operation to it, and may subsequently produce one or more output records to its sinks.</li>\n</ul>\n<p>There are two individual processors in the topology:</p>\n<ul>\n<li><strong>Source Processor</strong>: A source processor is a special type of stream processor that does not have any upstream processors. It produces an input stream to its topology from one or multiple Kafka topics by consuming records from these topics and forwarding them to its down-stream processors.</li>\n<li><strong>Sink Processor</strong>: A sink processor is a special type of stream processor that does not have down-stream processors. It sends any received records from its up-stream processors to a specified Kafka topic.</li>\n</ul>\n<p><img src=\"/a6722490a32c205bf1f07a2796039933/streams-architecture-topology.webp\" alt=\"Toplogy Example\"></p>\n<ul>\n<li><strong>Kstream</strong>: KStream is nothing but that, a Kafka Stream. It’s a never-ending flow of data in a stream. Each piece of data — a record or a fact — is a collection of key-value pairs. Data records in a record stream are always interpreted as an \"INSERT\".</li>\n<li><strong>KTable</strong>: A KTable is just an abstraction of the stream, where only the latest value is kept. Data records in a record stream are always interpreted as an \"UPDATE\".</li>\n</ul>\n<p>There is actually a close relationship between streams and tables, the so-called stream-table duality</p>\n<h2 id=\"implementing-kafka-streams\" style=\"position:relative;\"><a href=\"#implementing-kafka-streams\" aria-label=\"implementing kafka streams permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Implementing Kafka Streams</h2>\n<p>Let's Start with the Setup using Scala instead of Java. The Kafka Streams DSL for Scala library is a wrapper over the existing Java APIs for Kafka Streams DSL.</p>\n<p>To Setup things, we need to create a <code>KafkaStreams</code> Instance. It needs a topology and configuration (<code>java.util.Properties</code>). We also need a input topic and output topic. Let's look through a simple example of sending data from an input topic to an output topic using the Streams API</p>\n<p>You can create a topic using the below commands (need to have Kafka pre installed)</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"shell\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">kafka-topics --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic inputTopic</span>\n<span class=\"grvsc-line\">kafka-topics --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic outputTopic</span></code></pre>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"scala\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">val config: Properties = {</span>\n<span class=\"grvsc-line\">    val properties = new Properties()</span>\n<span class=\"grvsc-line\">    properties.put(StreamsConfig.APPLICATION_ID_CONFIG, &quot;your-application&quot;)</span>\n<span class=\"grvsc-line\">    properties.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, &quot;localhost:9092&quot;)</span>\n<span class=\"grvsc-line\">    properties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, &quot;latest&quot;)</span>\n<span class=\"grvsc-line\">    properties.put(StreamsConfig.PROCESSING_GUARANTEE_CONFIG, StreamsConfig.EXACTLY_ONCE)</span>\n<span class=\"grvsc-line\">    properties.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String())</span>\n<span class=\"grvsc-line\">    properties.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String())</span>\n<span class=\"grvsc-line\">    properties</span>\n<span class=\"grvsc-line\">    }</span></code></pre>\n<p>StreamsBuilder provide the high-level Kafka Streams DSL to specify a Kafka Streams topology.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"scala\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">val builder: StreamsBuilder = new StreamsBuilder</span></code></pre>\n<p>Creates a KStream from the specified topics.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"scala\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">val inputStream: KStream[String,String] = builder.stream(inputTopic, Consumed.`with`(Serdes.String(), Serdes.String()))</span></code></pre>\n<p>Store the input stream to the output topic.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"scala\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">inputStream.to(outputTopic)(producedFromSerde(Serdes.String(),Serdes.String())</span></code></pre>\n<p>Starts the Streams Application</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"scala\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">val kEventStream = new KafkaStreams(builder.build(), config)</span>\n<span class=\"grvsc-line\">kEventStream.start()</span>\n<span class=\"grvsc-line\">sys.ShutdownHookThread {</span>\n<span class=\"grvsc-line\">      kEventStream.close(10, TimeUnit.SECONDS)</span>\n<span class=\"grvsc-line\">    }</span></code></pre>\n<p>You can send data to the input topic using </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"shell\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">kafka-console-producer --broker-list localhost:9092 --topic inputTopic</span></code></pre>\n<p>And can fetch the data from the output topic using</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"shell\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">kafka-console-consumer --bootstrap-server localhost:9092 --topic outputTopic --from-beginning</span></code></pre>\n<p>You can add the necessary dependencies in your build file for sbt or pom file for maven. Below is an example for build.sbt.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"sbt\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">// Kafka</span>\n<span class=\"grvsc-line\">libraryDependencies += &quot;org.apache.kafka&quot; %% &quot;kafka-streams-scala&quot; % &quot;2.0.0&quot;</span>\n<span class=\"grvsc-line\">libraryDependencies += &quot;javax.ws.rs&quot; % &quot;javax.ws.rs-api&quot; % &quot;2.1&quot; artifacts( Artifact(&quot;javax.ws.rs-api&quot;, &quot;jar&quot;, &quot;jar&quot;)) // this is a workaround. There is an upstream dependency that causes trouble in SBT builds.</span></code></pre>\n<p>Let us modify the code a little bit to try out a WordCount example:\nThe code splits the sentences into words and groups by word as a key and the number of occurences or count as value and is being sent to the output topic by converting the KTable to KStream.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"scala\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">val textLines: KStream[String, String] = builder.stream[String, String](inputTopic)</span>\n<span class=\"grvsc-line\">val wordCounts: KTable[String, Long] = textLines</span>\n<span class=\"grvsc-line\">\t\t.flatMapValues(textLine =&gt; textLine.toLowerCase.split(&quot;\\\\W+&quot;))</span>\n<span class=\"grvsc-line\">\t\t.groupBy((_, word) =&gt; word)</span>\n<span class=\"grvsc-line\">\t\t.count()(materializedFromSerde(Serdes.String(),Serdes.Long()))</span>\n<span class=\"grvsc-line\">\twordCounts.toStream.to(outputTopic)(producedFromSerde(Serdes.String(),Serdes.Long())</span></code></pre>\n<p>With the above process, we can now implement a simple streaming application or a word count application using Kafka Streams in Scala. If you want to set up kafka on Windows, here is a quick guide to implement apache <a href=\"/quick-kafka-installation/\">kafka on windows OS</a>. </p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n</style>","frontmatter":{"date":"July 01, 2020","updated_date":null,"description":"Learn about Kafka Streams, key concepts and highlights with simple streaming or a word count application using Kafka Streams in Scala","title":"Kafka Streams: A stream processing guide","tags":["Scala","Kafka","Kafka Streams"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/0b37b7b26ad97126a6657a2447528848/58556/header.webp","srcSet":"/static/0b37b7b26ad97126a6657a2447528848/61e93/header.webp 200w,\n/static/0b37b7b26ad97126a6657a2447528848/1f5c5/header.webp 400w,\n/static/0b37b7b26ad97126a6657a2447528848/58556/header.webp 800w,\n/static/0b37b7b26ad97126a6657a2447528848/99238/header.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Priyadarshan Mohanty","github":"priyadarshan1995","avatar":null}}}}]},"markdownRemark":{"excerpt":"Introduction Ever wondered how apps like Spotify, Netflix, or Slack manage seamless login experiences across devices? Many of them use JWT…","fields":{"slug":"/engineering/how-to-integrate-jwt/"},"html":"<h2 id=\"introduction\" style=\"position:relative;\"><a href=\"#introduction\" aria-label=\"introduction permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Introduction</h2>\n<p>Ever wondered how apps like Spotify, Netflix, or Slack manage seamless login experiences across devices? Many of them use JWT, or JSON Web Tokens, a compact, stateless method for securely transmitting user identity and session data across services.</p>\n<p>With JWT token authentication, identity information is embedded in a signed token, allowing you to maintain user sessions without server-side storage. This approach is highly scalable and ideal for modern architectures like SPAs, mobile apps, and microservices.</p>\n<p>In this blog, we’ll walk you through what is JWT, why use it, and how to implement JWT authentication using LoginRadius. </p>\n<p>You’ll learn what JWT is, why it’s effective, and how it works in real-world applications. We'll cover both integration methods (IDX and Direct API), generating your signing key, managing sessions, storing the JWT token securely, and applying best practices throughout.</p>\n<p>Whether you're a developer, product manager, or IAM architect, this guide offers a complete foundation for implementing JWT token authentication into your application stack.</p>\n<h2 id=\"what-is-jwt\" style=\"position:relative;\"><a href=\"#what-is-jwt\" aria-label=\"what is jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is JWT?</h2>\n<p><a href=\"https://www.loginradius.com/blog/engineering/jwt/\">JSON Web Token (JWT)</a> is an open standard (RFC 7519) used to transmit information securely between parties as a JSON object. It’s compact, self-contained, and digitally signed, making it a reliable format for authentication and authorization across modern applications.</p>\n<p>A JWT consists of three parts:</p>\n<ol>\n<li><strong>Header –</strong> Contains metadata like the type of token and signing algorithm (e.g., HS256).</li>\n<li><strong>Payload –</strong> Stores the actual data or “claims,” such as user ID, roles, and token expiry.</li>\n<li><strong>Signature –</strong> A cryptographic hash that ensures the token hasn’t been tampered with.</li>\n</ol>\n<p><em>Example of a token structure:</em></p>\n<p>&#x3C;base64Header>.&#x3C;base64Payload>.&#x3C;signature></p>\n<h2 id=\"why-use-jwt\" style=\"position:relative;\"><a href=\"#why-use-jwt\" aria-label=\"why use jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Why Use JWT?</h2>\n<ul>\n<li><strong>Stateless Authentication</strong>: No server-side session storage is needed — the token holds all necessary user info. </li>\n<li><strong>Portable</strong>: Works seamlessly across domains, services, and APIs. </li>\n<li><strong>Scalable</strong>: Ideal for microservices, SPAs, mobile apps, and serverless functions. </li>\n<li><strong>Interoperable</strong>: JWTs are supported across many languages and frameworks.</li>\n</ul>\n<h2 id=\"how-jwt-works\" style=\"position:relative;\"><a href=\"#how-jwt-works\" aria-label=\"how jwt works permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How JWT Works?</h2>\n<p><img src=\"/f29edbf2978577390c7ffa02e9bc4dda/lr-JWT-authentication.webp\" alt=\"Flowchart illustrating LoginRadius JWT authentication via Identity Provider (IDP), showing user redirection from login icon to login page, authentication with IDP, JWT token validation, and subsequent redirection to the customer&#x27;s website or error page based on validation results.\"></p>\n<ol>\n<li>A user logs in with credentials. </li>\n<li>Your app (or identity provider like LoginRadius) issues a signed JWT. </li>\n<li>The client stores the token and sends it with each request (usually in the Authorization header). </li>\n<li>The server validates the token’s signature and claims. </li>\n<li>If valid, access is granted — without any session stored on the backend.</li>\n</ol>\n<p>JWT simplifies identity verification, especially when you're building apps that talk to APIs or need to scale without centralized session storage.</p>\n<h2 id=\"jwt-authentication-with-loginradius-overview\" style=\"position:relative;\"><a href=\"#jwt-authentication-with-loginradius-overview\" aria-label=\"jwt authentication with loginradius overview permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>JWT Authentication with LoginRadius: Overview</h2>\n<p>LoginRadius provides robust support for JWT (JSON Web Token) authentication, which allows for flexible and secure access control across different digital platforms. Whether you're building a fully custom identity flow or using a pre-built interface, the platform supports various integration approaches depending on your architecture.</p>\n<p>If you're looking to understand how to implement JWT token authentication effectively, LoginRadius offers two primary implementation models that cater to different levels of customization and control:</p>\n<h3 id=\"1-idx-implementation--jwt-through-a-hosted-login-page\" style=\"position:relative;\"><a href=\"#1-idx-implementation--jwt-through-a-hosted-login-page\" aria-label=\"1 idx implementation  jwt through a hosted login page permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. IDX Implementation – JWT through a Hosted Login Page</h3>\n<p>The IDX-hosted login approach enables secure, standards-compliant, JWT-based authentication without requiring you to build a custom login interface. This is a strategic option for fast, compliant, and user-friendly deployments.</p>\n<ul>\n<li>The Identity Experience Framework (IDX) comes with a fully custom branded hosted login page.</li>\n<li>Once the user logs in and gets enrolled, the user’s JWTs are automatically generated and issued. These tokens can be utilized for managing user sessions and accessing the APIs.</li>\n<li>This approach simplifies deployment without compromising on user experience and security standards.</li>\n</ul>\n<h3 id=\"configuration-steps\" style=\"position:relative;\"><a href=\"#configuration-steps\" aria-label=\"configuration steps permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>Configuration Steps:</strong></h3>\n<ol>\n<li>Enable JWT Login</li>\n<li>Go to <a href=\"https://console.loginradius.com/authentication/authentication-configuration\">authentication configuration settings</a> and enable JWT Login in the Admin Console.</li>\n</ol>\n<p><img src=\"/9fb19dd9c88c7916aeebd03ab6e661b7/lr-admin-console.webp\" alt=\"Screenshot of LoginRadius Admin Console showing JWT Custom IDP configuration interface with options for provider name, algorithm (HS256), key entry, clock skew, and expiration time settings.\"></p>\n<ol start=\"2\">\n<li>Specify your signing algorithm and expiry policy, and define your JWT Secret Key.</li>\n<li>Input a secure JWT signing key.</li>\n<li>Specify token expiry duration (e.g., 15–60 minutes)</li>\n<li>Select the desired algorithm —HS256 for symmetric signing (same key signs and verifies)</li>\n<li>RS256 for asymmetric signing, where LoginRadius securely stores the private key used to sign the JWT.</li>\n<li>Your app or backend service uses the public key to validate the token signature.</li>\n<li>LoginRadius provides a JWKS (JSON Web Key Set) endpoint to dynamically fetch and rotate public keys, ensuring trust without key exposure.</li>\n<li>Update IDX Template for Callback</li>\n<li>Modify your IDX login page template to retrieve the JWT post-login. You can access the token via redirect URL parameters or secure JavaScript callbacks.</li>\n</ol>\n<h3 id=\"example-response\" style=\"position:relative;\"><a href=\"#example-response\" aria-label=\"example response permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example Response:</h3>\n<p>{</p>\n<p>  \"access_token\": \"eyJhbGciOiJIUzI1NiIsInR...\",</p>\n<p>  \"expires_in\": 1800</p>\n<p>}</p>\n<p>This integration approach works best for all teams that want effective identity workflows without the complexity of building proprietary login screens, something that is crucial for customer portals, onboarding of mobile applications, and even managing access for business partners.</p>\n<h3 id=\"2-direct-api-implementation--self-managed-login\" style=\"position:relative;\"><a href=\"#2-direct-api-implementation--self-managed-login\" aria-label=\"2 direct api implementation  self managed login permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. Direct API Implementation – Self Managed Login</h3>\n<p>If you’re building a custom login UI or working in a headless environment, LoginRadius lets you generate and handle JWTs directly through its <a href=\"https://www.loginradius.com/docs/api/v2/customer-identity-api/\">Authentication APIs</a>. Here’s how you can programmatically perform token authentication using the classic method:</p>\n<ul>\n<li>For custom front-end applications, LR offers an API to authenticate users and issue JWT tokens.</li>\n<li>In response to the login request, the developers are provided with signed tokens that can be validated on the client’s side or by downstream services.</li>\n<li>This method is best fit for enterprise applications that have complex custom workflows or are designed to be embedded into other applications.</li>\n</ul>\n<h3 id=\"configuration-steps-1\" style=\"position:relative;\"><a href=\"#configuration-steps-1\" aria-label=\"configuration steps 1 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>Configuration Steps:</strong></h3>\n<h4 id=\"step-1-authenticate-via-api\" style=\"position:relative;\"><a href=\"#step-1-authenticate-via-api\" aria-label=\"step 1 authenticate via api permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 1: Authenticate via API:</h4>\n<ul>\n<li>\n<p>Send a POST login request to the LR Authentication URL: </p>\n<p>POST /identity/v2/auth/login</p>\n</li>\n</ul>\n<p>Include the user’s credentials (email + password) in the request body.</p>\n<h4 id=\"step-2-get-jwt-in-response\" style=\"position:relative;\"><a href=\"#step-2-get-jwt-in-response\" aria-label=\"step 2 get jwt in response permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 2: Get JWT in Response</h4>\n<ul>\n<li>If the user credentials are authentic, then the JWT token will be available in response.</li>\n</ul>\n<p>{</p>\n<p> \"access_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",</p>\n<p> \"expires_in\": 3600</p>\n<p>}</p>\n<h4 id=\"step-3-jwt-decoding-and-validation\" style=\"position:relative;\"><a href=\"#step-3-jwt-decoding-and-validation\" aria-label=\"step 3 jwt decoding and validation permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 3: JWT Decoding and Validation</h4>\n<ul>\n<li>Use any JWT library (e.g., jsonwebtoken for Node.js or pyjwt for Python) to decode the token.</li>\n<li>Validate the signature using your configured secret key.</li>\n<li>Confirm claims like exp, iat, aud, and iss.</li>\n</ul>\n<h4 id=\"step-4-set-custom-claims-optional\" style=\"position:relative;\"><a href=\"#step-4-set-custom-claims-optional\" aria-label=\"step 4 set custom claims optional permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 4: Set Custom Claims (Optional)</h4>\n<p>With LoginRadius, it is possible to customize the payload to include user roles and/or any additional metadata. You can set custom JWT claims on the Admin Console.</p>\n<p>With this method, you have complete customization over login flows while using LoginRadius to issue signed JWTs for user session management.</p>\n<p><strong>NOTE-</strong> With either method, LoginRadius ensures that JWTs are securely signed, optionally short-lived, and compatible with standard token validation libraries, making integration seamless for everyone.</p>\n<p>To get started with JWT implementation, you can<a href=\"https://www.loginradius.com/docs/single-sign-on/federated-sso/jwt-login/jwt-implementation-guide/\"> read our complete developer documentation</a>. </p>\n<h2 id=\"hosted-login-vs-direct-api\" style=\"position:relative;\"><a href=\"#hosted-login-vs-direct-api\" aria-label=\"hosted login vs direct api permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Hosted Login vs Direct API</h2>\n<p><img src=\"/15ec02ac98d24a9f1f28e5d0f06b9174/IDX-vs-Direct-API-JWT.webp\" alt=\"Illustration showing IDX vs Direct API JWT flow diagram comparing LoginRadius JWT authentication methods via Hosted Login Page (IDX) and Custom Login UI using Direct API, illustrating user login, JWT issuance, and token return process.\"></p>\n<h2 id=\"what-is-session-management-and-how-it-works-with-jwt\" style=\"position:relative;\"><a href=\"#what-is-session-management-and-how-it-works-with-jwt\" aria-label=\"what is session management and how it works with jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is Session Management and How It Works with JWT</h2>\n<p><a href=\"https://www.loginradius.com/blog/identity/user-session-management/\">Session management </a>is how your app keeps track of a user after they log in so they don’t have to prove who they are with every request.</p>\n<p>In traditional apps, sessions are stored on the server using session IDs. Every time a request comes in, the server checks that session ID to verify the user.</p>\n<p>In modern apps, especially SPAs and APIs, JWTs are used to manage sessions without needing server-side storage; this is called stateless session management. The token itself carries the user’s identity, roles, and expiration details. As long as the token is valid, the user stays logged in.</p>\n<p>Good session management ensures:</p>\n<ul>\n<li>Security against session hijacking</li>\n<li>Fast user validation without hitting a database</li>\n<li>Smooth experiences with token refresh strategies</li>\n</ul>\n<h2 id=\"how-loginradius-handles-session-management-with-jwt\" style=\"position:relative;\"><a href=\"#how-loginradius-handles-session-management-with-jwt\" aria-label=\"how loginradius handles session management with jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How LoginRadius Handles Session Management with JWT:</h2>\n<ol>\n<li>\n<p>User Logs In </p>\n<ul>\n<li>LoginRadius returns an access token (JWT) and, optionally, a refresh token.</li>\n</ul>\n</li>\n<li>\n<p>Client Stores the Token </p>\n<ul>\n<li>Access tokens are stored in memory, sessionStorage, or secure cookies. </li>\n<li>They’re sent on every request via the Authorization: Bearer header. </li>\n</ul>\n</li>\n<li>\n<p>Access Token Expiry </p>\n<ul>\n<li>These tokens are short-lived by design (e.g., 15–30 minutes). </li>\n<li>Once expired, the client can use the refresh token to request a new access token. </li>\n</ul>\n</li>\n<li>\n<p>Token Renewal </p>\n<ul>\n<li>LoginRadius validates the refresh token and issues a new JWT, i.e., no user re-authentication is needed. </li>\n<li>Refresh tokens can be revoked at any time.</li>\n</ul>\n</li>\n<li>Logout and Token Revocation Strategy</li>\n</ol>\n<p>When the user logs out, both the access token and refresh token should be cleared from client storage.</p>\n<ul>\n<li>The refresh token can be explicitly revoked via the LoginRadius API, terminating the ability to renew sessions. </li>\n<li>\n<p>However, access tokens are stateless and cannot be revoked mid-lifecycle unless: </p>\n<ul>\n<li>You maintain a blacklist of token IDs (jti claims) and check them on each request. </li>\n<li>You use short-lived access tokens to limit exposure naturally. </li>\n<li>Or, you rotate your JWT signing key, invalidating all previously issued tokens. </li>\n</ul>\n</li>\n</ul>\n<p>Combining these strategies gives you greater control over token misuse and enables a robust, enterprise-grade logout flow. </p>\n<p><a href=\"https://www.loginradius.com/resource/whitepaper/secure-api-using-oauth2\"><img src=\"/e55ae4bbc8ce62e13f03e46e29ebe7cc/api-economy.webp\" alt=\"illustration showing LoginRadius free downloadable resource named API economy is transforming digitization: how to secure it using oauth 2.0.\"></a></p>\n<h2 id=\"how-to-store-jwt-tokens\" style=\"position:relative;\"><a href=\"#how-to-store-jwt-tokens\" aria-label=\"how to store jwt tokens permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to Store JWT Tokens?</h2>\n<p>When you implement JWT-based authentication, the client (browser or mobile app) needs a way to store the access token and, optionally, the refresh token after they are issued by the authentication server. This stored token is then attached to every subsequent request to prove the user's identity.</p>\n<p>Choosing where to store the JWT is a crucial security decision. The most common storage options are:</p>\n<ul>\n<li>localStorage</li>\n<li>sessionStorage</li>\n<li>HTTP-only cookies</li>\n</ul>\n<p>Each option has trade-offs between security, accessibility, and persistence, and the right choice depends on your application's architecture and threat model.</p>\n<h4 id=\"recommended-storage-strategy\" style=\"position:relative;\"><a href=\"#recommended-storage-strategy\" aria-label=\"recommended storage strategy permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Recommended Storage Strategy</h4>\n<ul>\n<li>\n<p>Access Tokens </p>\n<ul>\n<li>For SPAs: store in memory or sessionStorage for short-term access </li>\n<li>If stored in the browser, protect against XSS </li>\n</ul>\n</li>\n<li>\n<p>Refresh Tokens</p>\n<ul>\n<li>Always store the JWT refresh token in HTTP-only secure cookies to prevent JavaScript access. This adds a critical layer of protection against XSS attacks.</li>\n<li>Combine with SameSite=Strict or SameSite=Lax attributes to mitigate CSRF risks and ensure the JWT refresh token is only sent in intended contexts.</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"best-practices-for-storing-jwts\" style=\"position:relative;\"><a href=\"#best-practices-for-storing-jwts\" aria-label=\"best practices for storing jwts permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Best Practices for Storing JWTs</h2>\n<ol>\n<li>Never store sensitive tokens (like refresh tokens) in localStorage or sessionStorage.</li>\n<li>Use Secure and HttpOnly flags with cookies to prevent JavaScript access and ensure transmission only over HTTPS.</li>\n<li>Set the SameSite=Strict or Lax attribute on cookies to protect against CSRF.</li>\n<li>Use short-lived access tokens and rotate refresh tokens regularly.</li>\n<li>Implement CSP (Content Security Policy) to reduce XSS risk.</li>\n<li>Avoid storing any tokens in frontend code (e.g., hardcoded in JS files).</li>\n</ol>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>JWT authentication with LoginRadius offers a modern, stateless approach to managing sessions across distributed systems. The IDX integration is ideal for rapid deployment, while the Direct API model is best for organizations needing deep customization and integration flexibility.</p>\n<p>With robust token signing, refresh capabilities, and centralized control, LoginRadius provides a future-ready foundation for secure, scalable identity architecture. <a href=\"https://www.loginradius.com/contact-us?utm_source=blog&#x26;utm_medium=web&#x26;utm_campaign=how-to-integrate-jwt\">Contact us</a> to know more about JWT authentication and implementation guide. </p>\n<h2 id=\"faqs\" style=\"position:relative;\"><a href=\"#faqs\" aria-label=\"faqs permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>FAQs</h2>\n<h3 id=\"1-what-is-jwt-authentication-used-for\" style=\"position:relative;\"><a href=\"#1-what-is-jwt-authentication-used-for\" aria-label=\"1 what is jwt authentication used for permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. What is JWT authentication used for?</h3>\n<p><strong>A:</strong> JWT authentication securely verifies user identities, enabling stateless session management across web, mobile apps, and microservices without server-side session storage.</p>\n<h3 id=\"2-how-does-loginradius-simplify-jwt-integration\" style=\"position:relative;\"><a href=\"#2-how-does-loginradius-simplify-jwt-integration\" aria-label=\"2 how does loginradius simplify jwt integration permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. How does LoginRadius simplify JWT integration?</h3>\n<p><strong>A:</strong> LoginRadius simplifies JWT integration by offering hosted <a href=\"https://www.loginradius.com/docs/single-sign-on/federated-sso/jwt-login/jwt-implementation-guide/\">IDX login pages </a>and direct API-based authentication methods, enabling rapid deployment and deep customization.</p>\n<h3 id=\"3-is-jwt-authentication-secure\" style=\"position:relative;\"><a href=\"#3-is-jwt-authentication-secure\" aria-label=\"3 is jwt authentication secure permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3. Is JWT authentication secure?</h3>\n<p><strong>A:</strong> Yes, JWT authentication is secure when implemented with best practices like short-lived tokens, secure storage methods, signature validation, and refresh token rotation.</p>\n<h3 id=\"4-can-jwt-tokens-be-revoked-with-loginradius\" style=\"position:relative;\"><a href=\"#4-can-jwt-tokens-be-revoked-with-loginradius\" aria-label=\"4 can jwt tokens be revoked with loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>4. Can JWT tokens be revoked with LoginRadius?</h3>\n<p><strong>A:</strong> Yes, LoginRadius allows<a href=\"https://www.loginradius.com/docs/api/v2/customer-identity-api/refresh-token/revoke-refresh-token/?q=revoke+jwt\"> revocation of JWT</a> refresh tokens explicitly, and supports strategies like short-lived tokens and key rotation to manage token lifecycles securely.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"April 15, 2025","updated_date":null,"description":"Discover JWT (JSON Web Token) authentication, its advantages, and how to integrate it seamlessly using LoginRadius' hosted IDX and Direct API methods for secure, scalable identity management.","title":"JWT Authentication with LoginRadius: Quick Integration Guide","tags":["JWT","JSON Web Token","Authentication","Authorization"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":0.7782101167315175,"src":"/static/4cedb7829f98208cbc6d5a9aea4e983d/58556/how-to-integrate-jwt.webp","srcSet":"/static/4cedb7829f98208cbc6d5a9aea4e983d/61e93/how-to-integrate-jwt.webp 200w,\n/static/4cedb7829f98208cbc6d5a9aea4e983d/1f5c5/how-to-integrate-jwt.webp 400w,\n/static/4cedb7829f98208cbc6d5a9aea4e983d/58556/how-to-integrate-jwt.webp 800w,\n/static/4cedb7829f98208cbc6d5a9aea4e983d/1cc9f/how-to-integrate-jwt.webp 896w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Kundan Singh","github":null,"avatar":null}}}},"pageContext":{"limit":6,"skip":198,"currentPage":34,"type":"//engineering//","numPages":53,"pinned":"5c425581-f474-5ae9-abe7-cf5342db2aaa"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}