{"componentChunkName":"component---src-templates-blog-list-template-js","path":"/engineering/36","result":{"data":{"allMarkdownRemark":{"edges":[{"node":{"excerpt":"In this blog, we’ll be implementing authentication via Google in a Go web application. For this, we’ll be using Goth - Multi-Provider…","fields":{"slug":"/engineering/google-authentication-with-golang-and-goth/"},"html":"<p>In this blog, we’ll be implementing authentication via Google in a Go web application. For this, we’ll be using <a href=\"https://github.com/markbates/goth\">Goth</a> - Multi-Provider Authentication Package for Go</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>Basic knowledge of HTML/CSS</li>\n<li>A basic understanding of Go Language</li>\n<li>Latest GoLang version installed on your system</li>\n</ul>\n<h3 id=\"step-1-create-a-google-client-id-and-client-secret\" style=\"position:relative;\"><a href=\"#step-1-create-a-google-client-id-and-client-secret\" aria-label=\"step 1 create a google client id and client secret permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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: Create a Google client ID and client secret</h3>\n<p>We can create a  client ID and client secret using its <a href=\"https://console.developers.google.com/\">Google API Console</a>. You need to follow below steps once you open Google API Console</p>\n<ul>\n<li>From the project drop-down, select an existing project, or create a new one by selecting Create a new project</li>\n<li>In the sidebar under \"APIs &#x26; Services\", select Credentials</li>\n<li>In the Credentials tab, select the Create credentials drop-down list, and choose OAuth client ID.</li>\n<li>Under Application type, select Web application.</li>\n<li>In Authorized redirect URI use <code>http://localhost:3000/auth/google/callback</code></li>\n<li>Press the Create button and copy the generated client ID and client secret</li>\n</ul>\n<p><strong>Note:</strong> If Google doesn't support <code>http://localhost:3000</code>, then use <code>http://127.0.0.1:3000</code></p>\n<h3 id=\"step-2-initialize-a-go-project-using-go-modules\" style=\"position:relative;\"><a href=\"#step-2-initialize-a-go-project-using-go-modules\" aria-label=\"step 2 initialize a go project using go modules permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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: Initialize a Go project using Go modules</h3>\n<p>First in an empty folder run the below command</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">go mod init googleauth</span></code></pre>\n<p><code>go mod init</code> creates a new go.mod file and automatically imports dependencies when you will run go program</p>\n<h3 id=\"step-3-writing-golang-server-code-to-accept-web-requests\" style=\"position:relative;\"><a href=\"#step-3-writing-golang-server-code-to-accept-web-requests\" aria-label=\"step 3 writing golang server code to accept web requests permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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: Writing golang server code to accept web requests</h3>\n<p>Create a file <strong>main.go</strong> in the root folder of your app and add the following code: </p>\n<p>A small description for packages used in below code</p>\n<ul>\n<li><strong>gorilla/pat:</strong>  A lightweight HTTP router for Go</li>\n<li><strong>markbates/goth:</strong>  Multi-Provider Authentication Package for Go</li>\n<li><strong>gorilla/sessions:</strong>  To save information from google in session and use it on the success page</li>\n<li><strong>markbates/goth/providers/google:</strong>  Google authentication provider by Goth</li>\n<li><strong>html/template:</strong> Go package to parse Html files</li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">package</span><span class=\"mtk1\"> main</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk8\">&quot;fmt&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk8\">&quot;html/template&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk8\">&quot;net/http&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk8\">&quot;log&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk8\">&quot;github.com/gorilla/pat&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk8\">&quot;github.com/markbates/goth&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk8\">&quot;github.com/markbates/goth/gothic&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk8\">&quot;github.com/markbates/goth/providers/google&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk8\">&quot;github.com/gorilla/sessions&quot;</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\">func</span><span class=\"mtk1\"> </span><span class=\"mtk11\">main</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">key</span><span class=\"mtk1\"> := </span><span class=\"mtk8\">&quot;Secret-session-key&quot;</span><span class=\"mtk1\">  </span><span class=\"mtk3\">// Replace with your SESSION_SECRET or similar</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">maxAge</span><span class=\"mtk1\"> := </span><span class=\"mtk7\">86400</span><span class=\"mtk1\"> * </span><span class=\"mtk7\">30</span><span class=\"mtk1\">  </span><span class=\"mtk3\">// 30 days</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">isProd</span><span class=\"mtk1\"> := </span><span class=\"mtk4\">false</span><span class=\"mtk1\">       </span><span class=\"mtk3\">// Set to true when serving over https</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">store</span><span class=\"mtk1\"> := sessions.</span><span class=\"mtk11\">NewCookieStore</span><span class=\"mtk1\">([]</span><span class=\"mtk11\">byte</span><span class=\"mtk1\">(key))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  store.</span><span class=\"mtk11\">MaxAge</span><span class=\"mtk1\">(maxAge)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">store.Options.Path</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;/&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">store.Options.HttpOnly</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">true</span><span class=\"mtk1\">   </span><span class=\"mtk3\">// HttpOnly should always be enabled</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">store.Options.Secure</span><span class=\"mtk1\"> = isProd</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">gothic.Store</span><span class=\"mtk1\"> = store</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  goth.</span><span class=\"mtk11\">UseProviders</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    google.</span><span class=\"mtk11\">New</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;our-google-client-id&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;our-google-client-secret&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;http://localhost:3000/auth/google/callback&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;email&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;profile&quot;</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  )</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">p</span><span class=\"mtk1\"> := pat.</span><span class=\"mtk11\">New</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  p.</span><span class=\"mtk11\">Get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/auth/{provider}/callback&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk4\">func</span><span class=\"mtk1\">(res http.ResponseWriter, req *http.Request) {</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">user</span><span class=\"mtk1\">, </span><span class=\"mtk12\">err</span><span class=\"mtk1\"> := gothic.</span><span class=\"mtk11\">CompleteUserAuth</span><span class=\"mtk1\">(res, req)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> err != </span><span class=\"mtk4\">nil</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      fmt.</span><span class=\"mtk11\">Fprintln</span><span class=\"mtk1\">(res, err)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">t</span><span class=\"mtk1\">, </span><span class=\"mtk12\">_</span><span class=\"mtk1\"> := template.</span><span class=\"mtk11\">ParseFiles</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;templates/success.html&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    t.</span><span class=\"mtk11\">Execute</span><span class=\"mtk1\">(res, user)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  })</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  p.</span><span class=\"mtk11\">Get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/auth/{provider}&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk4\">func</span><span class=\"mtk1\">(res http.ResponseWriter, req *http.Request) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    gothic.</span><span class=\"mtk11\">BeginAuthHandler</span><span class=\"mtk1\">(res, req)</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\">  p.</span><span class=\"mtk11\">Get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk4\">func</span><span class=\"mtk1\">(res http.ResponseWriter, req *http.Request) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">t</span><span class=\"mtk1\">, </span><span class=\"mtk12\">_</span><span class=\"mtk1\"> := template.</span><span class=\"mtk11\">ParseFiles</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;templates/index.html&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    t.</span><span class=\"mtk11\">Execute</span><span class=\"mtk1\">(res, </span><span class=\"mtk4\">false</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  log.</span><span class=\"mtk11\">Println</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;listening on localhost:3000&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  log.</span><span class=\"mtk11\">Fatal</span><span class=\"mtk1\">(http.</span><span class=\"mtk11\">ListenAndServe</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;:3000&quot;</span><span class=\"mtk1\">, p))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p><strong>Note:</strong> The callback URL in <code>google.New</code> should be the same as used in the google app configuration.</p>\n<p>If it is hard to understand the code, Here is the description of all the routes used in the code mentioned above</p>\n<ul>\n<li><strong>\"/\":</strong>  The root route will render the index.html page</li>\n<li><strong>/auth/{provider}:</strong>  When you click on SignIn button it will hit this route and <code>gothic.BeginAuthHandler</code> will redirect you to google authentication URL</li>\n<li><strong>/auth/{provider}/callback:</strong>  Once you have authenticated Google will send all the user details on this callback URL, and goth will save the info in session also which can be used in other routes also if needed</li>\n</ul>\n<h3 id=\"step-4-creating-a-login-and-profile-page\" style=\"position:relative;\"><a href=\"#step-4-creating-a-login-and-profile-page\" aria-label=\"step 4 creating a login and profile page permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 4: Creating a Login and Profile page</h3>\n<p>Create an html file under path <strong>templates/index.html</strong>, it will render into a nice looking social login page:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!-- </span><span class=\"mtk12\">templates</span><span class=\"mtk1\">/</span><span class=\"mtk12\">index</span><span class=\"mtk1\">.</span><span class=\"mtk12\">html</span><span class=\"mtk1\"> --&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!</span><span class=\"mtk12\">doctype</span><span class=\"mtk1\"> </span><span class=\"mtk12\">html</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Google SignIn</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">link</span><span class=\"mtk1\"> </span><span class=\"mtk12\">rel</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;stylesheet&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> &lt;!-- load bulma css --&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">link</span><span class=\"mtk1\"> </span><span class=\"mtk12\">rel</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;stylesheet&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> &lt;!-- load fontawesome --&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">style</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        body        </span><span class=\"mtk4\">{</span><span class=\"mtk1\"> </span><span class=\"mtk12\">padding</span><span class=\"mtk1\">-</span><span class=\"mtk12\">top</span><span class=\"mtk1\">:70</span><span class=\"mtk12\">px</span><span class=\"mtk1\">; </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">style</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;container&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;jumbotron text-center text-success&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">span</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;fa fa-lock&quot;</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> Social Authentication</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Login or Register with:</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/auth/google&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;btn btn-danger&quot;</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">span</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;fa fa-google&quot;</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> SignIn with Google</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">a</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> </span></span></code></pre>\n<p>After it we will create an Html file under path <strong>templates/success.html</strong>, it will be used to show the user profile information we will get after authenticated by google</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!-- </span><span class=\"mtk12\">templates</span><span class=\"mtk1\">/</span><span class=\"mtk12\">success</span><span class=\"mtk1\">.</span><span class=\"mtk12\">html</span><span class=\"mtk1\"> --&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!</span><span class=\"mtk12\">doctype</span><span class=\"mtk1\"> </span><span class=\"mtk12\">html</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Google SignIn</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">link</span><span class=\"mtk1\"> </span><span class=\"mtk12\">rel</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;stylesheet&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> &lt;!-- load bulma css --&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">link</span><span class=\"mtk1\"> </span><span class=\"mtk12\">rel</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;stylesheet&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> &lt;!-- load fontawesome --&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">style</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          body        </span><span class=\"mtk4\">{</span><span class=\"mtk1\"> </span><span class=\"mtk12\">padding</span><span class=\"mtk1\">-</span><span class=\"mtk12\">top</span><span class=\"mtk1\">:70</span><span class=\"mtk12\">px</span><span class=\"mtk1\">; </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">style</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;container&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;jumbotron&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;text-success  text-center&quot;</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">span</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;fa fa-user&quot;</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> Profile Information</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;row&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;col-sm-6&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;well&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">strong</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Id</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">strong</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">{</span><span class=\"mtk1\">{.</span><span class=\"mtk12\">UserID</span><span class=\"mtk1\">}</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">strong</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Email</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">strong</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">{</span><span class=\"mtk1\">{.</span><span class=\"mtk12\">Email</span><span class=\"mtk1\">}</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">strong</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Name</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">strong</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">{</span><span class=\"mtk1\">{.</span><span class=\"mtk12\">Name</span><span class=\"mtk1\">}</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p><strong>Note:</strong> Here we are also using bootstrap and font-awesome css to make our web pages look good. </p>\n<p>We have finished building our social login page, let's run the application by below command</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">go run main.go</span></code></pre>\n<p>Once our server is running, we can see our social login page on <code>http://localhost:3000/</code></p>\n<p><img src=\"/c05a4db3947d9bd9a468e28cc5e86484/go_google_login.webp\" alt=\"Social Authentication Page\" title=\"Social Authentication Page\"></p>\n<p>We need to click on <strong>SignIn with Google button</strong>, which will redirect us to the google login page.</p>\n<p><img src=\"/6db1545bee5e34124e225af45e79bdbb/google_login.webp\" alt=\"Google Login\" title=\"Google Login\"></p>\n<p>After login with our google credentials, it will redirect back to our application and on the success page, we can see the details of the logged-in user and can save this detail in a database for future use also.</p>\n<p><img src=\"/2e3a98823cff3dfe444e53eab89cf151/go_google_profile.webp\" alt=\"Social Profile Info\" title=\"Social Profile Info\"></p>\n<p>As we have seen it is fairly easy to build a google social authentication system with Go language and Goth package, You can found the complete code used in this tutorial on our <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/GoLang/GoogleAuthenticationGoth\">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 .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk17 { color: #808080; }\n</style>","frontmatter":{"date":"June 11, 2020","updated_date":null,"description":"Learn how to implement Google OAuth2 Authentication in Golang using Goath","title":"Google OAuth2 Authentication in Golang","tags":["Go","SocialLogin","Oauth"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.6666666666666667,"src":"/static/5960f981e6b283300239a1ecf91728b0/e9589/google_golang.webp","srcSet":"/static/5960f981e6b283300239a1ecf91728b0/61e93/google_golang.webp 200w,\n/static/5960f981e6b283300239a1ecf91728b0/1f5c5/google_golang.webp 400w,\n/static/5960f981e6b283300239a1ecf91728b0/e9589/google_golang.webp 500w","sizes":"(max-width: 500px) 100vw, 500px"}}},"author":{"id":"Puneet Singh","github":"puneetsingh24","avatar":null}}}},{"node":{"excerpt":"This blog article will guide you to add \"log in with LinkedIn\"\nfunctionality in your application. Here we will be implementing Linkedin…","fields":{"slug":"/engineering/linkedin-login-using-node-passport/"},"html":"<p>This blog article will guide you to add \"log in with LinkedIn\"\nfunctionality in your application. Here we will be implementing <strong>Linkedin Login</strong>  using NodeJS and <a href=\"http://www.passportjs.org/\">Passport</a>. </p>\n<p>Passport is an authentication middleware for Node, which authenticates requests and delegates all other functionality to the application. Considering the unique application requirements, Passport has stuck to authentication mechanisms known as strategies. In the blog, we will be implementing a similar strategy for Login with Linkedin.</p>\n<h2 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:</h2>\n<ol>\n<li>Basic Knowledge of NodeJS </li>\n<li>Node JS should be installed on your system. </li>\n</ol>\n<h2 id=\"steps-to-configure\" style=\"position:relative;\"><a href=\"#steps-to-configure\" aria-label=\"steps to configure permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps to configure</h2>\n<ol>\n<li>Creating Linkedin <code>APP_ID</code> and <code>APP_SECRET</code></li>\n<li>Go to <a href=\"https://www.linkedin.com/developers/\">Developer Linkedin</a> and login with your Linkedin account. </li>\n<li>Once you have registered, click on the <code>create app</code> link and add the required details to create an app</li>\n</ol>\n<p><img src=\"/75132ca3ed5b7cd02270d0e280055008/create-app.webp\" alt=\"Create Linkedin APP\" title=\"Create Linkedin APP\"></p>\n<p>Provide basic details about your app:</p>\n<ul>\n<li>App name</li>\n<li>Company</li>\n<li>Privacy policy URL</li>\n<li>Business email</li>\n<li>\n<p>App logo</p>\n<ul>\n<li>After creating apps go to the <code>auth</code> tab in the navigation bar as shown below. You can now copy your secret and ID from here </li>\n</ul>\n<p><img src=\"/a78c4aa6cfc27a4af94c9233d52f3538/app-credentials.webp\" alt=\"App ID and Secret\" title=\"App ID and Sceret\"></p>\n</li>\n<li>\n<p>Now enough, let's move to code, First of all, create a directory named <code>Linkedin-node-authentication</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">mkdir Linkedin-node-authentication</span></code></pre>\n</li>\n<li>Move to the directory <code>Linkedin-node-authentication/</code></li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">  cd Linkedin-node-authentication</span></code></pre>\n<ol start=\"4\">\n<li>In the root create a file <code>package.json</code> and copy the following code </li>\n</ol>\n<p>The dependencies, we are going to use in the projects are </p>\n<ul>\n<li><code>express</code> : Node web framework</li>\n<li><code>express-session</code> Session managment of express</li>\n<li><code>passport</code> Authentication middleware for Node.js </li>\n<li><code>passport-linkedin-oauth2</code> A simple passport strategy for LinkedIn OAuth2 <a href=\"http://www.passportjs.org/packages/passport-linkedin-oauth2/\">passport linkedin oauth2</a></li>\n<li><code>ejs</code> - Templating engine</li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"json\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">&quot;name&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;linkedin-login-node&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">&quot;version&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;1.0.0&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">&quot;description&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Basic application for setting up Linkedin login using node and passport&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">&quot;main&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;index.js&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">&quot;scripts&quot;</span><span class=\"mtk1\">: {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">&quot;test&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;echo </span><span class=\"mtk6\">\\&quot;</span><span class=\"mtk8\">Error: no test specified</span><span class=\"mtk6\">\\&quot;</span><span class=\"mtk8\"> && exit 1&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">&quot;start&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;node server.js&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">&quot;author&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;LoginRadius&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">&quot;license&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;ISC&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">&quot;dependencies&quot;</span><span class=\"mtk1\">: {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">&quot;ejs&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;^3.1.2&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">&quot;express&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;^4.17.1&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">&quot;express-session&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;^1.17.1&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">&quot;passport&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;^0.4.1&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">&quot;passport-linkedin-oauth2&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;^2.0.0&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<ol start=\"5\">\n<li>\n<p>After this run the following command in the terminal</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm install</span></code></pre>\n</li>\n<li>Now create a file named <code>server.js</code> and paste the following code  </li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">express</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;express&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">app</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">express</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">session</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;express-session&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">passport</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;passport&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">LinkedInStrategy</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;passport-linkedin-oauth2&#39;</span><span class=\"mtk1\">).</span><span class=\"mtk12\">Strategy</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">routes</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;./routes.js&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">config</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;./config&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">set</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;view engine&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;ejs&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk11\">session</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">resave:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">false</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">saveUninitialized:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">secret:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;SECRET&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}));</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk12\">passport</span><span class=\"mtk1\">.</span><span class=\"mtk11\">initialize</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\">passport</span><span class=\"mtk1\">.</span><span class=\"mtk11\">session</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">passport</span><span class=\"mtk1\">.</span><span class=\"mtk11\">serializeUser</span><span class=\"mtk1\">(</span><span class=\"mtk4\">function</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">user</span><span class=\"mtk1\">, </span><span class=\"mtk12\">cb</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">cb</span><span class=\"mtk1\">(</span><span class=\"mtk4\">null</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">passport</span><span class=\"mtk1\">.</span><span class=\"mtk11\">deserializeUser</span><span class=\"mtk1\">(</span><span class=\"mtk4\">function</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">obj</span><span class=\"mtk1\">, </span><span class=\"mtk12\">cb</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">cb</span><span class=\"mtk1\">(</span><span class=\"mtk4\">null</span><span class=\"mtk1\">, </span><span class=\"mtk12\">obj</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">passport</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">LinkedInStrategy</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">clientID:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">config</span><span class=\"mtk1\">.</span><span class=\"mtk12\">linkedinAuth</span><span class=\"mtk1\">.</span><span class=\"mtk12\">clientID</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">clientSecret:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">config</span><span class=\"mtk1\">.</span><span class=\"mtk12\">linkedinAuth</span><span class=\"mtk1\">.</span><span class=\"mtk12\">clientSecret</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">callbackURL:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">config</span><span class=\"mtk1\">.</span><span class=\"mtk12\">linkedinAuth</span><span class=\"mtk1\">.</span><span class=\"mtk12\">callbackURL</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">scope:</span><span class=\"mtk1\"> [</span><span class=\"mtk8\">&#39;r_emailaddress&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;r_liteprofile&#39;</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}, </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">token</span><span class=\"mtk1\">, </span><span class=\"mtk12\">tokenSecret</span><span class=\"mtk1\">, </span><span class=\"mtk12\">profile</span><span class=\"mtk1\">, </span><span class=\"mtk12\">done</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk11\">done</span><span class=\"mtk1\">(</span><span class=\"mtk4\">null</span><span class=\"mtk1\">, </span><span class=\"mtk12\">profile</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">routes</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\">port</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">3000</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">listen</span><span class=\"mtk1\">(</span><span class=\"mtk12\">port</span><span class=\"mtk1\">, () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;App listening on port &#39;</span><span class=\"mtk1\"> + </span><span class=\"mtk12\">port</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span></code></pre>\n<ol start=\"7\">\n<li>Now create a file named <code>routes.js</code> in the root directory and paste the following code </li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">passport</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;passport&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">express</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;express&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">express</span><span class=\"mtk1\">.</span><span class=\"mtk11\">Router</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">render</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;pages/index.ejs&#39;</span><span class=\"mtk1\">); </span><span class=\"mtk3\">// load the index.ejs file</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/profile&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">isLoggedIn</span><span class=\"mtk1\">, </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">render</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;pages/profile.ejs&#39;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">user:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">user</span><span class=\"mtk1\"> </span><span class=\"mtk3\">// get the user out of session and pass to template</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/auth/linkedin&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">passport</span><span class=\"mtk1\">.</span><span class=\"mtk11\">authenticate</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;linkedin&#39;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">scope:</span><span class=\"mtk1\"> [</span><span class=\"mtk8\">&#39;r_emailaddress&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;r_liteprofile&#39;</span><span class=\"mtk1\">],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}));</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/auth/linkedin/callback&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">passport</span><span class=\"mtk1\">.</span><span class=\"mtk11\">authenticate</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;linkedin&#39;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">successRedirect:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;/profile&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">failureRedirect:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;/login&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }));</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/logout&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk11\">logout</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">redirect</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">isLoggedIn</span><span class=\"mtk1\">(</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">next</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk11\">isAuthenticated</span><span class=\"mtk1\">())</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk11\">next</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">redirect</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">module</span><span class=\"mtk1\">.</span><span class=\"mtk10\">exports</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">router</span><span class=\"mtk1\">;</span></span></code></pre>\n<ol start=\"7\">\n<li>Create a directory <code>views</code> and under this create a directory named <code>pages</code>. Under this folder create two pages named <code>profile.ejs</code> and <code>index.ejs</code></li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">// index.ejs</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!</span><span class=\"mtk12\">doctype</span><span class=\"mtk1\"> </span><span class=\"mtk12\">html</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Linkedin Node Authentication</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">link</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;https://fonts.googleapis.com/icon?family=Material+Icons&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">rel</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;stylesheet&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">link</span><span class=\"mtk1\"> </span><span class=\"mtk12\">rel</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;stylesheet&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">link</span><span class=\"mtk1\"> </span><span class=\"mtk12\">rel</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;stylesheet&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;text/css&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/css/materialize.min.css&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">style</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .linkedin </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">background</span><span class=\"mtk1\">-</span><span class=\"mtk12\">color</span><span class=\"mtk1\">: #0073</span><span class=\"mtk12\">b1</span><span class=\"mtk1\"> !</span><span class=\"mtk12\">important</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">color</span><span class=\"mtk1\">: #</span><span class=\"mtk12\">fff</span><span class=\"mtk1\"> !</span><span class=\"mtk12\">important</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .fa-linkedin-f:before,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .fa-linkedin:before </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">content</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;</span><span class=\"mtk6\">\\f</span><span class=\"mtk8\">0e1&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">style</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">nav</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;light-blue lighten-1&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">role</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;navigation&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;nav-wrapper container&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;logo-container&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;#&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;brand-logo&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Node Authentication</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">a</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">nav</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;section no-pad-bot&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;index-banner&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;container&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;row center&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;col s6 offset-s3&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;card&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;card-content&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">span</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;card-title&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Linkedin Login using Node and passport</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;card-action&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/auth/linkedin&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;waves-effect waves-light btn social linkedin&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">i</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;fa fa-linkedin&quot;</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">i</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> Sign in with Linkedin</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">a</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!- </span><span class=\"mtk12\">profile</span><span class=\"mtk1\">.</span><span class=\"mtk12\">ejs</span><span class=\"mtk1\">-&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!</span><span class=\"mtk12\">doctype</span><span class=\"mtk1\"> </span><span class=\"mtk12\">html</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">LinkedIn Node Authentication</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">link</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;https://fonts.googleapis.com/icon?family=Material+Icons&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">rel</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;stylesheet&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">link</span><span class=\"mtk1\"> </span><span class=\"mtk12\">rel</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;stylesheet&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;text/css&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/css/materialize.min.css&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">style</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .card:hover </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">box</span><span class=\"mtk1\">-</span><span class=\"mtk12\">shadow</span><span class=\"mtk1\">: </span><span class=\"mtk7\">0</span><span class=\"mtk1\"> 10</span><span class=\"mtk12\">px</span><span class=\"mtk1\"> 20</span><span class=\"mtk12\">px</span><span class=\"mtk1\"> </span><span class=\"mtk11\">rgba</span><span class=\"mtk1\">(</span><span class=\"mtk7\">0</span><span class=\"mtk1\">, </span><span class=\"mtk7\">0</span><span class=\"mtk1\">, </span><span class=\"mtk7\">0</span><span class=\"mtk1\">, </span><span class=\"mtk7\">0.19</span><span class=\"mtk1\">), </span><span class=\"mtk7\">0</span><span class=\"mtk1\"> 6</span><span class=\"mtk12\">px</span><span class=\"mtk1\"> 6</span><span class=\"mtk12\">px</span><span class=\"mtk1\"> </span><span class=\"mtk11\">rgba</span><span class=\"mtk1\">(</span><span class=\"mtk7\">0</span><span class=\"mtk1\">, </span><span class=\"mtk7\">0</span><span class=\"mtk1\">, </span><span class=\"mtk7\">0</span><span class=\"mtk1\">, </span><span class=\"mtk7\">0.23</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">margin</span><span class=\"mtk1\">-</span><span class=\"mtk12\">bottom</span><span class=\"mtk1\">: 54</span><span class=\"mtk12\">px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">style</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">nav</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;light-blue lighten-1&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">role</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;navigation&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;nav-wrapper container&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;logo-container&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;#&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;brand-logo&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Node Authentication</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">a</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/logout&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;right&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Logout</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">a</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">nav</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;section no-pad-bot&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;index-banner&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;container&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;row center&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;col s12&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;card&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;card-content blue lighten-3&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">span</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;card-title white-text&quot;</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">strong</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">i</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;large material-icons&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">person</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">i</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">strong</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;card-action&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h5</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">b</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">&lt;%= user.displayName %&gt;</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">b</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">h5</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">strong</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Linkedin id</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">strong</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">: &lt;%= user.id %&gt;</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<ol start=\"8\">\n<li>Finally, when you are done with the above code you can now write all your app details gathered in <em>step 1</em> to <code>config.js</code> file created in the root directory </li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">module</span><span class=\"mtk1\">.</span><span class=\"mtk10\">exports</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk8\">&#39;linkedinAuth&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;clientID&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;&lt;CLIENT_ID&gt;&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk3\">// your App ID</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;clientSecret&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;&lt;CLIENT_SECRET&gt;&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk3\">// your App Secret</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;callbackURL&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;http://127.0.0.1:3000/auth/linkedin/callback&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<ol start=\"9\">\n<li>Let's have a final check with the repository, aftre follwoing all the steps in the same pordr the directory structure of your code will look like below:  </li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">// Final directory structure</span>\n<span class=\"grvsc-line\">Linkedin-node-authentication/</span>\n<span class=\"grvsc-line\">  --|node_modules</span>\n<span class=\"grvsc-line\">  --|views/</span>\n<span class=\"grvsc-line\">    |--|pages/</span>\n<span class=\"grvsc-line\">    |----|error.ejs</span>\n<span class=\"grvsc-line\">    |----|profile.ejs</span>\n<span class=\"grvsc-line\">    |----|index.ejs</span>\n<span class=\"grvsc-line\">  --|config.js</span>\n<span class=\"grvsc-line\">  --|package.json</span>\n<span class=\"grvsc-line\">  --|package-lock.json</span>\n<span class=\"grvsc-line\">  --|routes.js</span>\n<span class=\"grvsc-line\">  --|server.js</span></code></pre>\n<ol start=\"10\">\n<li>Now run the server by executing below command in the directory <code>Linkedin-node-authentication/</code></li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm start</span></code></pre>\n<ol start=\"8\">\n<li>Visit the browser with the URL <code>http://localhost:3000</code></li>\n</ol>\n<p>  <img src=\"/bfd29e4b03283c3a5cfe67a43e18f3f5/linkedin-login-page.webp\" alt=\"Linkedin login home page\" title=\"Linkedin login home page\"></p>\n<p>  Click on the sign in button, and you will be asked to login through Linkedin. Once logged in you will be redirected to profile page as below:</p>\n<p>  <img src=\"/2c95500cf554892bb994a1e8d7cc90f8/linkedin-profile-page.webp\" alt=\"Linkedin login profile page\" title=\"Linkedin login profile page\"></p>\n<p>  The complete sample code for the above tutorial can be found <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/NodeJs/LinkedinLoginPassport\">here</a></p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk6 { color: #D7BA7D; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk17 { color: #808080; }\n</style>","frontmatter":{"date":"June 10, 2020","updated_date":null,"description":"Learn social login benefits and how we can implement LinkedIn Login on our website or mobile app.","title":"LinkedIn Login using Node JS and passport","tags":["LinkedIn","Login","NodeJs","PassportJS"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7699115044247788,"src":"/static/717d9ce34aacf1736c240b0fa8d67551/58556/linkedin_login_node.webp","srcSet":"/static/717d9ce34aacf1736c240b0fa8d67551/61e93/linkedin_login_node.webp 200w,\n/static/717d9ce34aacf1736c240b0fa8d67551/1f5c5/linkedin_login_node.webp 400w,\n/static/717d9ce34aacf1736c240b0fa8d67551/58556/linkedin_login_node.webp 800w,\n/static/717d9ce34aacf1736c240b0fa8d67551/99238/linkedin_login_node.webp 1200w,\n/static/717d9ce34aacf1736c240b0fa8d67551/135cd/linkedin_login_node.webp 1280w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Aman Agrawal","github":"aman-agrwl","avatar":null}}}},{"node":{"excerpt":"In this blog, we will see how we can read and write into a local file with the help of Deno First, we will create a program which will read…","fields":{"slug":"/engineering/read-and-write-in-a-local-file-with-deno/"},"html":"<p>In this blog, we will see how we can read and write into a local file with the help of Deno</p>\n<ul>\n<li>First, we will create a program which will read multiple quotes from a text file and then print a random quote on our screen </li>\n<li>Then we will take input from the user in the command line and write those inputs in a text file </li>\n</ul>\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 basic knowledge about Deno and you have latest Deno version installed on your system, if you haven't installed Deno on your system or never ran Deno code please look at this great introductory blog - <a href=\"/hello-world-deno/\">Hello world with Deno</a> </p>\n<h3 id=\"part-1-read-a-file-and-print-text-out-of-it\" style=\"position:relative;\"><a href=\"#part-1-read-a-file-and-print-text-out-of-it\" aria-label=\"part 1 read a file and print text out of it permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Part 1: Read a file and print text out of it</h3>\n<p>First, add a file called quotes.txt in the folder you want to run the Deno code, We will read these quotes with the help of Deno</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">Don&#39;t worry about what anybody else is going to do. The best way to predict the future is to invent it. - Alan Kay</span>\n<span class=\"grvsc-line\">Premature optimization is the root of all evil in programming. - Donald Knuth</span>\n<span class=\"grvsc-line\">Clarity and brevity sometimes are at odds. When they are, I choose clarity.  - Jacob Kaplan-Moss</span>\n<span class=\"grvsc-line\">Optimism is an occupational hazard of programming; feedback is the treatment. - Kent Beck</span>\n<span class=\"grvsc-line\">A lot of times, people don&#39;t know what they want until you show it to them.  - Steve Jobs</span>\n<span class=\"grvsc-line\">Nine people can&#39;t make a baby in a month. - Fred Brooks</span>\n<span class=\"grvsc-line\">A clever person solves a problem. A wise person avoids it. - Albert Einstein</span></code></pre>\n<p>And then create an index.ts file in which we will write Deno code, we can also write Deno code in javascript instead of Typescript, but as Deno is built on TypeScript we are using Typescript here</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">getQuotes</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">fileName</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">): </span><span class=\"mtk10\">Promise</span><span class=\"mtk1\">&lt;</span><span class=\"mtk10\">Array</span><span class=\"mtk1\">&lt;</span><span class=\"mtk10\">string</span><span class=\"mtk1\">&gt;&gt; </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">decoder</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">TextDecoder</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;utf-8&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">text</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">decoder</span><span class=\"mtk1\">.</span><span class=\"mtk11\">decode</span><span class=\"mtk1\">(</span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Deno</span><span class=\"mtk1\">.</span><span class=\"mtk11\">readFile</span><span class=\"mtk1\">(</span><span class=\"mtk12\">fileName</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">text</span><span class=\"mtk1\">.</span><span class=\"mtk11\">split</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=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">quotesArr</span><span class=\"mtk1\">: </span><span class=\"mtk10\">Array</span><span class=\"mtk1\">&lt;</span><span class=\"mtk10\">string</span><span class=\"mtk1\">&gt; = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">getQuotes</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;quotes.txt&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\">randomQuote</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\"> =  </span><span class=\"mtk12\">quotesArr</span><span class=\"mtk1\">[</span><span class=\"mtk10\">Math</span><span class=\"mtk1\">.</span><span class=\"mtk11\">floor</span><span class=\"mtk1\">(</span><span class=\"mtk10\">Math</span><span class=\"mtk1\">.</span><span class=\"mtk11\">random</span><span class=\"mtk1\">() * </span><span class=\"mtk12\">quotesArr</span><span class=\"mtk1\">.</span><span class=\"mtk12\">length</span><span class=\"mtk1\">)];</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">randomQuote</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>In the getQuotes function, we are using  Deno.readFile #readfile to read the contents of a file as an array of bytes and using <code>TextDecoder</code> to convert the bytes to string and then splitting it in a string array and return</p>\n<p>Then we are just picking a <code>randomQuote</code> with <code>Math.random</code> and <code>console.log</code> that on our screen</p>\n<p>To run the above code we need to put <code>--allow-read</code> flag in our command as shown below because we need to access the local filesystem to read the file.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">deno run --allow-read index.ts</span></code></pre>\n<p>Deno is secure by default, with no file, network, or environment access unless explicitly enabled. You can run <code>deno run --help</code> to see  all the available flags for different permissions</p>\n<p>Once your program run initially you will see that Deno is compiling the index.ts file and printing a random quote from quotes.txt, if you run the programme again without changing the code it will not compile it again and will just show another random quote.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">deno run --allow-read index.ts</span>\n<span class=\"grvsc-line\">Compile file:///C:/Users/PuneetSingh/Documents/deno_fs/index.ts</span>\n<span class=\"grvsc-line\">Premature optimization is the root of all evil in programming. - Donald Knuth</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">deno run --allow-read index.ts</span>\n<span class=\"grvsc-line\">A lot of times, people don&#39;t know what they want until you show it to them.  - Steve Jobs</span></code></pre>\n<h3 id=\"part-2-create-a-file-and-write-text-in-it\" style=\"position:relative;\"><a href=\"#part-2-create-a-file-and-write-text-in-it\" aria-label=\"part 2 create a file and write text in it permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Part 2: Create a file and write text in it</h3>\n<p>Let's create another TypeScript file write.ts and put the below code in it</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">readLines</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/std@v0.52.0/io/bufio.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Start typing...&#39;</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\">encoder</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">TextEncoder</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Deno</span><span class=\"mtk1\">.</span><span class=\"mtk11\">writeFile</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;input.txt&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Uint8Array</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// Listen to stdin input by readLines</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">for</span><span class=\"mtk1\"> </span><span class=\"mtk15\">await</span><span class=\"mtk1\">(</span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">line</span><span class=\"mtk1\"> </span><span class=\"mtk4\">of</span><span class=\"mtk1\"> </span><span class=\"mtk11\">readLines</span><span class=\"mtk1\">(</span><span class=\"mtk12\">Deno</span><span class=\"mtk1\">.</span><span class=\"mtk12\">stdin</span><span class=\"mtk1\">)) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">data</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">encoder</span><span class=\"mtk1\">.</span><span class=\"mtk11\">encode</span><span class=\"mtk1\">(</span><span class=\"mtk12\">line</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 class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Deno</span><span class=\"mtk1\">.</span><span class=\"mtk11\">writeFile</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;input.txt&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">data</span><span class=\"mtk1\">, {</span><span class=\"mtk12\">append:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Wrote the above text in input.txt</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></code></pre>\n<p>In the above code we are using <a href=\"https://github.com/denoland/std/blob/main/README.md\">readLines</a> to raed user input line by line, Every time we run the code <code>Deno.writeFile(\"input.txt\", new Uint8Array())</code> will create an empty <code>input.txt</code> file in the folder.</p>\n<p>Then <code>const line of readLines(Deno.stdin)</code> in a loop will wait for the user to input any text, as we will give any input  <code>Deno.writeFile</code> with <code>{append: true}</code> is used to append data in <code>input.txt</code></p>\n<p>Let's run the program, Once we run it, whatever text we will give to the program through standard input will be written to input.txt</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">deno run --allow-write write.ts</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">Start typing...</span>\n<span class=\"grvsc-line\">This is a demo for Deno</span>\n<span class=\"grvsc-line\">Wrote the above text in input.txt</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">In this demo, we will write some text in a file</span>\n<span class=\"grvsc-line\">Wrote the above text in input.txt</span></code></pre>\n<p>If you check the input.txt file you will found the content which was given as input</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">This is a demo for Deno</span>\n<span class=\"grvsc-line\">In this demo, we will write some text in a file</span></code></pre>\n<p>Now you know how to read from a text file and how to write in a text file with Deno, You can found the complete source code used in the above blog on our <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/Deno/ReadAndWriteInLocalFile\">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 .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk6 { color: #D7BA7D; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n</style>","frontmatter":{"date":"June 09, 2020","updated_date":null,"description":null,"title":"Read and Write in a local file with Deno","tags":["Deno"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.6666666666666667,"src":"/static/d11d2715523eeb315fdcc7727f48ec20/ad85c/deno_file_system.webp","srcSet":"/static/d11d2715523eeb315fdcc7727f48ec20/61e93/deno_file_system.webp 200w,\n/static/d11d2715523eeb315fdcc7727f48ec20/1f5c5/deno_file_system.webp 400w,\n/static/d11d2715523eeb315fdcc7727f48ec20/ad85c/deno_file_system.webp 600w","sizes":"(max-width: 600px) 100vw, 600px"}}},"author":{"id":"Puneet Singh","github":"puneetsingh24","avatar":null}}}},{"node":{"excerpt":"What is Deno? Deno is a JavaScript/TypeScript runtime with secure defaults and great developer experience. It's built on V8, Rust, and Tokio…","fields":{"slug":"/engineering/build-a-cli-tool-using-deno/"},"html":"<h3 id=\"what-is-deno\" style=\"position:relative;\"><a href=\"#what-is-deno\" aria-label=\"what is deno permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is Deno?</h3>\n<p>Deno is a JavaScript/TypeScript runtime with secure defaults and great developer experience. It's built on V8, Rust, and Tokio.\nI suggest you watch these talks by Ryan: He talks about his mistakes with Nodejs <a href=\"https://www.youtube.com/watch?v=M3BM9TB-8yA&#x26;vl=en\">here</a> and a more in-depth look into deno <a href=\"https://www.youtube.com/watch?v=z6JRlx5NC9E\">here</a></p>\n<h5 id=\"features\" style=\"position:relative;\"><a href=\"#features\" aria-label=\"features permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Features</h5>\n<ul>\n<li>Secure by default. No file, network, or environment access (unless explicitly enabled).</li>\n<li>Supports TypeScript out of the box.</li>\n<li>Ships a single executable (deno).</li>\n<li>Has built-in utilities like a dependency inspector (deno info) and a code formatter (deno fmt).</li>\n<li>Has a set of reviewed (audited) standard modules that are guaranteed to work with Deno.\nScripts can be bundled into a single JavaScript file.</li>\n</ul>\n<h3 id=\"lets-build-something\" style=\"position:relative;\"><a href=\"#lets-build-something\" aria-label=\"lets build something permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Let's Build Something!!!</h3>\n<p>In this article, we're going to build a simple cli tool to demonstrate some of the features of <a href=\"https://deno.land/\">deno</a>. Our cli will be interacting with a <strong>COVID</strong> API to fetch live data.</p>\n<blockquote>\n<p>Requirement: make sure you have deno installed. If you don't, refer to this <a href=\"/hello-world-deno/\">link</a>. It's pretty straightforward.</p>\n</blockquote>\n<p>Deno has the entry file <code>mod.ts</code> so we will follow the same in this article if you are following this article along with the coding you can create a folder named <code>covid-cli</code>, inside that folder you can create a file called <code>mod.ts</code> and copy the below code there.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"ts\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">args</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">Deno</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">parse</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/std/flags/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">dir</span><span class=\"mtk1\">(</span><span class=\"mtk11\">parse</span><span class=\"mtk1\">(</span><span class=\"mtk12\">args</span><span class=\"mtk1\">));</span></span></code></pre>\n<p>Here the <code>parse(args, options = {});</code> contains two parameters where args is an <code>Array</code> and <code>options</code> is an object, let try to run the above code using this cmd.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">deno run mod.ts arg1 -f hello --flag World --booleanFlag</span></code></pre>\n<p>After running the above code you will see the <strong>output</strong> as</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">{ _: [ &quot;arg1&quot; ], f: &quot;hello&quot;, flag: &quot;World&quot;, booleanFlag: true }</span></code></pre>\n<blockquote>\n<p>The first property in the object is always an array containing all arguments that did not have an option associated with them(i.e it doesn't match -f or --flag). If you do not pass a corresponding value to a flag, it defaults to true.</p>\n</blockquote>\n<p>I will be using the <a href=\"https://documenter.getpostman.com/view/10808728/SzS8rjbc?version=latest\">this</a> postman doc for all the COVID related API and we will perform the below to action through our CLI.</p>\n<ol>\n<li>A summary of new and total cases globally updated daily.</li>\n<li>A summary of new and total cases per country updated daily.</li>\n</ol>\n<p>Let's write out the function for our first command, so our <code>mod.ts</code> file will look like this.</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=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">args</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">Deno</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">parse</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/std/flags/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// flags:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// -h, --help: display help message</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// -g, --global: display global stats</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// -c, --country: get data of mentioned country</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\">BASE_URL</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;https://api.covid19api.com/&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">parsedArgs</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">parse</span><span class=\"mtk1\">(</span><span class=\"mtk12\">args</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">getGlobalStats</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">`</span><span class=\"mtk4\">${</span><span class=\"mtk12\">BASE_URL</span><span class=\"mtk4\">}</span><span class=\"mtk8\">summary`</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">data</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&quot;Global&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Here, we have an async function that returns the data from our API call. We're making a fetch request (yes, deno has browser functionality in-built) to the API endpoint to get the global stat of covid19.</p>\n<p>The function for the second command looks very similar, just we need to filter our data only for a particular country which is provided.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">getCountryStats</span><span class=\"mtk1\">(</span><span class=\"mtk12\">country</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">country</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">`</span><span class=\"mtk4\">${</span><span class=\"mtk12\">BASE_URL</span><span class=\"mtk4\">}</span><span class=\"mtk8\">summary`</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">data</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">index</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">data</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&quot;Countries&quot;</span><span class=\"mtk1\">].</span><span class=\"mtk11\">findIndex</span><span class=\"mtk1\">((</span><span class=\"mtk12\">c</span><span class=\"mtk1\">: </span><span class=\"mtk10\">any</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">c</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Country</span><span class=\"mtk1\">.</span><span class=\"mtk11\">toLowerCase</span><span class=\"mtk1\">() === </span><span class=\"mtk12\">country</span><span class=\"mtk1\">.</span><span class=\"mtk11\">toLowerCase</span><span class=\"mtk1\">())</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">index</span><span class=\"mtk1\"> !== -</span><span class=\"mtk7\">1</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&quot;Countries&quot;</span><span class=\"mtk1\">][</span><span class=\"mtk12\">index</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=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Country Not Found&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Country Name is needed&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>We will now write our <code>main()</code> function. We have a switch statement to check the first flag that was passed and calls the appropriate function. The default case simply displays a welcome message. Let add the below code in our <code>mod.ts</code> file</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">async function main() {</span>\n<span class=\"grvsc-line\">  switch (Object.keys(parsedArgs)[1]) {</span>\n<span class=\"grvsc-line\">    case &quot;help&quot;:</span>\n<span class=\"grvsc-line\">    case &quot;h&quot;:</span>\n<span class=\"grvsc-line\">      console.log(displayHelpMsg());</span>\n<span class=\"grvsc-line\">      break;</span>\n<span class=\"grvsc-line\">    case &quot;global&quot;:</span>\n<span class=\"grvsc-line\">    case &quot;g&quot;:</span>\n<span class=\"grvsc-line\">      await getGlobalStats();</span>\n<span class=\"grvsc-line\">      break;</span>\n<span class=\"grvsc-line\">    case &quot;country&quot;:</span>\n<span class=\"grvsc-line\">    case &quot;c&quot;:</span>\n<span class=\"grvsc-line\">       let country = parsedArgs.c || parsedArgs.country || &quot;&quot;</span>\n<span class=\"grvsc-line\">       await getCountryStats(country)</span>\n<span class=\"grvsc-line\">       break;</span>\n<span class=\"grvsc-line\">    default:</span>\n<span class=\"grvsc-line\">       console.log(displayHelpMsg());</span>\n<span class=\"grvsc-line\">  }</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">main()</span></code></pre>\n<p>And our <code>displayHelpMsg()</code> will look something like this</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">function displayHelpMsg() {</span>\n<span class=\"grvsc-line\">  return &quot;flags:\\n-h, --help: display help message\\n-g, --global: display global stats\\n-c, --country: get data of mentioned country &quot;;</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<h3 id=\"testing-time\" style=\"position:relative;\"><a href=\"#testing-time\" aria-label=\"testing time permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 Time!!!</h3>\n<p>To test our program, we're going to run $ deno run <code>--allow-net mod.ts -g</code>. We should get the following result:</p>\n<ul>\n<li>For Global Records</li>\n</ul>\n<p><img src=\"/85d4eea654795fc2487ba21e718208c2/global-data.webp\" alt=\"global-data\"></p>\n<ul>\n<li>For Country Wise Record</li>\n</ul>\n<p><img src=\"/bed833551bfe7ac83846d3ff633589d5/country-data.webp\" alt=\"country-data\"></p>\n<ul>\n<li>For Help</li>\n</ul>\n<p><img src=\"/b87a71d3e6b03df9f6d912499aeb25bd/help.webp\" alt=\"help\"></p>\n<p>That's all there is for our cli tool. If you'd like to see the full code, the repository is linked <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/Deno/covid-cli\">here</a>. In conclusion, Deno is a very exciting project especially because you get all the benefits of typescript out of the box without the need to compile your files to js. </p>\n<p>You can build a lot with it, ranging from cli Programs to HTTP servers. Do have a look at one of my <a href=\"/a-webapp-in-deno/\">blog</a> where I have built a basic calculator app using the <a href=\"https://deno.land/x/abc@v1.3.3\">abc</a> module.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n</style>","frontmatter":{"date":"June 08, 2020","updated_date":null,"description":null,"title":"Build A Simple CLI Tool using Deno","tags":["Deno","CLI","Programming"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7857142857142858,"src":"/static/c24ce77aa8d49761ef8a949cc2a9e06c/58556/cli-tool.webp","srcSet":"/static/c24ce77aa8d49761ef8a949cc2a9e06c/61e93/cli-tool.webp 200w,\n/static/c24ce77aa8d49761ef8a949cc2a9e06c/1f5c5/cli-tool.webp 400w,\n/static/c24ce77aa8d49761ef8a949cc2a9e06c/58556/cli-tool.webp 800w,\n/static/c24ce77aa8d49761ef8a949cc2a9e06c/ffc94/cli-tool.webp 860w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Mohammed Modi","github":"mohammed786","avatar":null}}}},{"node":{"excerpt":"Deno, the creation of Ryan Dahl is a simple, modern, and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust. As…","fields":{"slug":"/engineering/create-rest-api-in-deno/"},"html":"<p>Deno, the creation of Ryan Dahl is a simple, modern, and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust. As Deno 1.0.0 has released, there is much-awaited curiosity amongst developers around working with this new stack.</p>\n<p>When it comes to learning a new language, the first thing that comes to our mind is the creation of a todo app, supporting CRUD functionality. So here we will be creating a very simple Todo application using the Deno. </p>\n<p>So before starting I assume you have installed Deno on your system, if not then you can find the link <a href=\"/hello-world-deno/\">here</a>.\nFor the database, we will be using the <code>JSON</code> file as of now to completely focus on creating web API using Deno. Not more words and now let's start.</p>\n<p>The file structure we are going to follow is as below</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">  // Final directory structure</span>\n<span class=\"grvsc-line\">  deno-todo-api/</span>\n<span class=\"grvsc-line\">    --|controllers/</span>\n<span class=\"grvsc-line\">      |--|todo.ts</span>\n<span class=\"grvsc-line\">      |data/</span>\n<span class=\"grvsc-line\">      |--|todos.ts</span>\n<span class=\"grvsc-line\">      |interfaces/</span>\n<span class=\"grvsc-line\">      |--|Todo.ts</span>\n<span class=\"grvsc-line\">      |routes/</span>\n<span class=\"grvsc-line\">      |--|todo.ts</span>\n<span class=\"grvsc-line\">    --|server.ts</span>\n<span class=\"grvsc-line\">  </span></code></pre>\n<p>At any point in time, if you are stuck somewhere, you can follow this link to get the complete <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/Deno/RestAPIWithDeno\">code</a>.</p>\n<ol>\n<li>Create a directory named <code>deno-todo-api</code> and move into that directory </li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">  mkdir deno-todo-api && cd deno-todo-api</span></code></pre>\n<ol start=\"2\">\n<li>Create the file <code>server.ts</code> in the root of the directory. </li>\n<li>Write the following code into the <code>server.ts</code> file to start a server</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Application</span><span class=\"mtk1\">, </span><span class=\"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@v17.1.4/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">app</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Application</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">port</span><span class=\"mtk1\">: </span><span class=\"mtk10\">number</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">8080</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"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 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\">response</span><span class=\"mtk1\"> }: { </span><span class=\"mtk12\">response</span><span class=\"mtk1\">: </span><span class=\"mtk10\">any</span><span class=\"mtk1\"> }) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Rest API tutorial with Deno&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">routes</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk12\">router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">allowedMethods</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;running on port &#39;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">port</span><span class=\"mtk1\">);</span></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></code></pre>\n<p>Unlike <code>NodeJS</code> Deno does not need the <code>package.json</code> file for dependency management. Dependency management is simplified by having a list of modules and their respective URLs. </p>\n<p>Here we have used <a href=\"https://deno.land/x/oak\">oak</a>, a middleware framework for Deno's HTTP server, including a router middleware.</p>\n<ol start=\"4\">\n<li><code>server.ts</code> is the entry point for our web application. To check it run the following command in the root directory</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">deno run --allow-net server.ts</span></code></pre>\n<p>Open the browser and hit the URL <code>http://localhost:8080/</code></p>\n<p>You can see the following output in your browser</p>\n<p><img src=\"/a36b331956a234f26c49283ce04a1f31/output_localhost.webp\" alt=\"Browser output\"></p>\n<ol start=\"5\">\n<li>Now following the directory structure, we will create following folders in our project with the help of below command</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">mkdir controllers data interfaces routes</span></code></pre>\n<ol start=\"6\">\n<li>First of all, we will create dummy data to play with our todo APIs.Go to the data folder and create a file called <code>todos.ts</code> and the following code into it</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"typescript\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">v4</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/std/uuid/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// interface</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Todo</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;../interfaces/Todo.ts&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">todos</span><span class=\"mtk1\">: </span><span class=\"mtk10\">Todo</span><span class=\"mtk1\">[] = [</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">v4</span><span class=\"mtk1\">.</span><span class=\"mtk11\">generate</span><span class=\"mtk1\">(),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">task:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;Hello world app with Deno&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">done:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">v4</span><span class=\"mtk1\">.</span><span class=\"mtk11\">generate</span><span class=\"mtk1\">(),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">task:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;Simple Rest API with Deno&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">done:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">false</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">];</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">todos</span><span class=\"mtk1\">;</span></span></code></pre>\n<p>We will be using <code>v4</code>  provided by the <code>uuid</code> module to generate unique IDs.</p>\n<ol start=\"7\">\n<li>Now create a file in <code>interface/</code> folder <code>Todo.ts</code> and paste the following code. </li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"typescript\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">interface</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Todo</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">id</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">task</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">done</span><span class=\"mtk1\">: </span><span class=\"mtk10\">boolean</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>What are the interfaces??</p>\n<p>An interface defines the specifications of an entity. </p>\n<blockquote>\n<p>One of TypeScript’s core principles is that type checking focuses on the shape that values have. In TypeScript, interfaces fill the role of naming these types and are a powerful way of defining contracts within your code as well as contracts with code outside of your project.</p>\n</blockquote>\n<ol start=\"8\">\n<li>Now create a file named <code>todo.ts</code> in <code>controllers/</code> directory and paste the following code</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"typescript\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">v4</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/std/uuid/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// interfaces</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Todo</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../interfaces/Todo.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// stubs</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">todos</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../data/todos.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">getAll</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> ({ </span><span class=\"mtk12\">response</span><span class=\"mtk1\"> }: { </span><span class=\"mtk12\">response</span><span class=\"mtk1\">: </span><span class=\"mtk10\">any</span><span class=\"mtk1\"> }) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">200</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">data:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">todos</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">create</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    { </span><span class=\"mtk12\">request</span><span class=\"mtk1\">, </span><span class=\"mtk12\">response</span><span class=\"mtk1\"> }: { </span><span class=\"mtk12\">request</span><span class=\"mtk1\">: </span><span class=\"mtk10\">any</span><span class=\"mtk1\">; </span><span class=\"mtk12\">response</span><span class=\"mtk1\">: </span><span class=\"mtk10\">any</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">request</span><span class=\"mtk1\">.</span><span class=\"mtk11\">body</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (!</span><span class=\"mtk12\">request</span><span class=\"mtk1\">.</span><span class=\"mtk12\">hasBody</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">400</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Please provide the task detail and  status&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">newTodo</span><span class=\"mtk1\">: </span><span class=\"mtk10\">Todo</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">v4</span><span class=\"mtk1\">.</span><span class=\"mtk11\">generate</span><span class=\"mtk1\">(),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">task:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">body</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\">.</span><span class=\"mtk12\">todo</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">done:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">false</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">data</span><span class=\"mtk1\"> = [...</span><span class=\"mtk12\">todos</span><span class=\"mtk1\">, </span><span class=\"mtk12\">newTodo</span><span class=\"mtk1\">];</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">data</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">getById</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    { </span><span class=\"mtk12\">params</span><span class=\"mtk1\">, </span><span class=\"mtk12\">response</span><span class=\"mtk1\"> }: { </span><span class=\"mtk12\">params</span><span class=\"mtk1\">: { </span><span class=\"mtk12\">id</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\"> }; </span><span class=\"mtk12\">response</span><span class=\"mtk1\">: </span><span class=\"mtk10\">any</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">todo</span><span class=\"mtk1\">: </span><span class=\"mtk10\">Todo</span><span class=\"mtk1\"> | </span><span class=\"mtk10\">undefined</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">todos</span><span class=\"mtk1\">.</span><span class=\"mtk11\">find</span><span class=\"mtk1\">((</span><span class=\"mtk12\">t</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">t</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk1\"> === </span><span class=\"mtk12\">params</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (!</span><span class=\"mtk12\">todo</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">404</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;No task found related to given ID&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">200</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">data:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">todo</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">update</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    { </span><span class=\"mtk12\">params</span><span class=\"mtk1\">, </span><span class=\"mtk12\">request</span><span class=\"mtk1\">, </span><span class=\"mtk12\">response</span><span class=\"mtk1\"> }: {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">params</span><span class=\"mtk1\">: { </span><span class=\"mtk12\">id</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">request</span><span class=\"mtk1\">: </span><span class=\"mtk10\">any</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">response</span><span class=\"mtk1\">: </span><span class=\"mtk10\">any</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">todo</span><span class=\"mtk1\">: </span><span class=\"mtk10\">Todo</span><span class=\"mtk1\"> | </span><span class=\"mtk10\">undefined</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">todos</span><span class=\"mtk1\">.</span><span class=\"mtk11\">find</span><span class=\"mtk1\">((</span><span class=\"mtk12\">t</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">t</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk1\"> === </span><span class=\"mtk12\">params</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (!</span><span class=\"mtk12\">todo</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">404</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;No todo found&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">request</span><span class=\"mtk1\">.</span><span class=\"mtk11\">body</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">updatedData</span><span class=\"mtk1\">: { </span><span class=\"mtk12\">task</span><span class=\"mtk1\">?: </span><span class=\"mtk10\">string</span><span class=\"mtk1\">; </span><span class=\"mtk12\">done</span><span class=\"mtk1\">?: </span><span class=\"mtk10\">boolean</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">body</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">newTodos</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">todos</span><span class=\"mtk1\">.</span><span class=\"mtk11\">map</span><span class=\"mtk1\">((</span><span class=\"mtk12\">t</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">t</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk1\"> === </span><span class=\"mtk12\">params</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk1\"> ? { ...</span><span class=\"mtk12\">t</span><span class=\"mtk1\">, ...</span><span class=\"mtk12\">updatedData</span><span class=\"mtk1\"> } : </span><span class=\"mtk12\">t</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">200</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">data:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">newTodos</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">delete</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    { </span><span class=\"mtk12\">params</span><span class=\"mtk1\">, </span><span class=\"mtk12\">response</span><span class=\"mtk1\"> }: { </span><span class=\"mtk12\">params</span><span class=\"mtk1\">: { </span><span class=\"mtk12\">id</span><span class=\"mtk1\">: </span><span class=\"mtk10\">string</span><span class=\"mtk1\"> }; </span><span class=\"mtk12\">response</span><span class=\"mtk1\">: </span><span class=\"mtk10\">any</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">allTodos</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">todos</span><span class=\"mtk1\">.</span><span class=\"mtk11\">filter</span><span class=\"mtk1\">((</span><span class=\"mtk12\">t</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">t</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk1\"> !== </span><span class=\"mtk12\">params</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">200</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">data:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">allTodos</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span></code></pre>\n<ol start=\"9\">\n<li>Now go to <code>routes</code> and create <code>todo.ts</code> file in it and paste the following code </li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"typescript\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Router</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/x/oak/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Router</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// controller</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">todoController</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../controllers/todo.ts&quot;</span><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;/todos&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">todoController</span><span class=\"mtk1\">.</span><span class=\"mtk12\">getAll</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  .</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/todos&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">todoController</span><span class=\"mtk1\">.</span><span class=\"mtk12\">create</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  .</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/todos/:id&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">todoController</span><span class=\"mtk1\">.</span><span class=\"mtk12\">getById</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  .</span><span class=\"mtk11\">put</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/todos/:id&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">todoController</span><span class=\"mtk1\">.</span><span class=\"mtk12\">update</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  .</span><span class=\"mtk11\">delete</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/todos/:id&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">todoController</span><span class=\"mtk1\">.</span><span class=\"mtk12\">delete</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\">;</span></span></code></pre>\n<ol start=\"10\">\n<li>Now since we have created the complete MVC project for our todo APIs, we will be going to update our main <code>server.ts</code> file with following code</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"typescript\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Application</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Router</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;https://deno.land/x/oak/mod.ts&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">todoRouter</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./routes/todo.ts&quot;</span><span class=\"mtk1\">; </span><span class=\"mtk3\">// added the router call</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">app</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Application</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">port</span><span class=\"mtk1\">: </span><span class=\"mtk10\">number</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">8080</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk12\">todoRouter</span><span class=\"mtk1\">.</span><span class=\"mtk11\">routes</span><span class=\"mtk1\">()); </span><span class=\"mtk3\">// Intitialize the router with our application. </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\">todoRouter</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=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addEventListener</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;listen&quot;</span><span class=\"mtk1\">, ({ </span><span class=\"mtk12\">secure</span><span class=\"mtk1\">, </span><span class=\"mtk12\">hostname</span><span class=\"mtk1\">, </span><span class=\"mtk12\">port</span><span class=\"mtk1\"> }) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">protocol</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">secure</span><span class=\"mtk1\"> ? </span><span class=\"mtk8\">&quot;https://&quot;</span><span class=\"mtk1\"> : </span><span class=\"mtk8\">&quot;http://&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">url</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">`</span><span class=\"mtk4\">${</span><span class=\"mtk12\">protocol</span><span class=\"mtk4\">}${</span><span class=\"mtk12\">hostname</span><span class=\"mtk1\"> ?? </span><span class=\"mtk8\">&quot;localhost&quot;</span><span class=\"mtk1\">}:</span><span class=\"mtk12\">$</span><span class=\"mtk1\">{</span><span class=\"mtk12\">port</span><span class=\"mtk1\">}</span><span class=\"mtk8\">`;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk8\">  console.log(`</span><span class=\"mtk12\">Listening</span><span class=\"mtk1\"> </span><span class=\"mtk12\">on</span><span class=\"mtk1\">: </span><span class=\"mtk12\">$</span><span class=\"mtk1\">{</span><span class=\"mtk12\">port</span><span class=\"mtk1\">}</span><span class=\"mtk8\">`);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk8\">});</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk8\">await app.listen({ port });</span></span></code></pre>\n<ol start=\"11\">\n<li>Now run again the server with the following command </li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">deno run --allow-net server.ts</span></code></pre>\n<p>Now open the postman and hit the get URL <code>http://localhost:8080/todos/</code></p>\n<p><img src=\"/5d4cd381f56310b0117435ea3cc06296/all_output.webp\" alt=\"Browser output\"></p>\n<p>To check the getByID router, copy the ID of any task and hit the URL like </p>\n<p><code>http://localhost:8080/todos/:id</code></p>\n<p>You will be getting output like below </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"json\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">&quot;data&quot;</span><span class=\"mtk1\">: {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;id&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;eeacacdc-e55b-4299-aab7-5f631a2e3975&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;task&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Hello world app with Deno&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;done&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk4\">true</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Similarly, we can verify the complete crud API created. Below is the reference of all APIs created in the blog post</p>\n<table>\n<thead>\n<tr>\n<th>API</th>\n<th>Method</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>http://localhost:8080/todos/</code></td>\n<td>GET</td>\n<td>Fetch All todos</td>\n</tr>\n<tr>\n<td><code>http://localhost:8080/todos/{id}</code></td>\n<td>GET</td>\n<td>Fetch todo by ID</td>\n</tr>\n<tr>\n<td><code>http://localhost:8080/todos/</code></td>\n<td>POST</td>\n<td>Create New todo</td>\n</tr>\n<tr>\n<td><code>http://localhost:8080/todos/{id}</code></td>\n<td>PUT</td>\n<td>Update todo by ID</td>\n</tr>\n<tr>\n<td><code>http://localhost:8080/todos/{id}</code></td>\n<td>DELETE</td>\n<td>Delete todo by ID</td>\n</tr>\n</tbody>\n</table>\n<p>You can find the complete code of the repo <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/Deno/RestAPIWithDeno\">here</a> </p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n</style>","frontmatter":{"date":"June 08, 2020","updated_date":null,"description":null,"title":"Create REST API using deno ","tags":["Deno","REST","API"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7699115044247788,"src":"/static/4a65a81c1ab5e2211f19e9aeeb888f6b/58556/task.webp","srcSet":"/static/4a65a81c1ab5e2211f19e9aeeb888f6b/61e93/task.webp 200w,\n/static/4a65a81c1ab5e2211f19e9aeeb888f6b/1f5c5/task.webp 400w,\n/static/4a65a81c1ab5e2211f19e9aeeb888f6b/58556/task.webp 800w,\n/static/4a65a81c1ab5e2211f19e9aeeb888f6b/99238/task.webp 1200w,\n/static/4a65a81c1ab5e2211f19e9aeeb888f6b/135cd/task.webp 1280w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Aman Agrawal","github":"aman-agrwl","avatar":null}}}},{"node":{"excerpt":"We're delightfully announcing the open source automation suite to test all the standard authentication cases of LoginRadius Identity…","fields":{"slug":"/engineering/opensource-automation-for-identity-experience-framework/"},"html":"<p>We're delightfully announcing the open source automation suite to test all the standard authentication cases of LoginRadius Identity Experience Framework.\nThe details have been given below.</p>\n<h3 id=\"link-to-the-repository\" style=\"position:relative;\"><a href=\"#link-to-the-repository\" aria-label=\"link to the repository permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Link to the repository:</h3>\n<p><a href=\"https://github.com/LoginRadius/idx-auto-tester/\">idx auto tester</a></p>\n<h3 id=\"about-loginradius-identity-experience-framework\" style=\"position:relative;\"><a href=\"#about-loginradius-identity-experience-framework\" aria-label=\"about loginradius identity experience framework permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>About LoginRadius Identity Experience Framework</h3>\n<p>Identity Experience Framework is a ready-to-use solution for all the necessary actions. It is a set of registration, authentication, and related web pages such as forgot password, profile. It allows you to customize the UI and UX elements as per your requirements.</p>\n<h3 id=\"why-to-use-this-automation-suite\" style=\"position:relative;\"><a href=\"#why-to-use-this-automation-suite\" aria-label=\"why to use this automation suite permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 to use this automation suite?</h3>\n<p>The Standard Authentication Functionality which is available with LoginRadius Identity Experience Framework can be tested via using these automation scripts. By running all the scripts, you can ensure your implementation.</p>\n<h3 id=\"what-is-the-technologyframework-used-to-build-this-automation-suite\" style=\"position:relative;\"><a href=\"#what-is-the-technologyframework-used-to-build-this-automation-suite\" aria-label=\"what is the technologyframework used to build this automation suite permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 the technology/framework used to build this automation suite?</h3>\n<ul>\n<li>The script is written in <a href=\"https://nightwatchjs.org/\">Nightwatch</a> framework.</li>\n<li><a href=\"https://nodejs.org/en/\">NodeJS</a> Core Assertion Testing Library is used for assertions.</li>\n</ul>\n<h3 id=\"test-cases-covered\" style=\"position:relative;\"><a href=\"#test-cases-covered\" aria-label=\"test cases covered permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test cases covered:</h3>\n<ul>\n<li>Registration</li>\n<li>Email Verification</li>\n<li>Login</li>\n<li>Change Password</li>\n<li>Invalid Scenarios</li>\n<li>Reset Password</li>\n<li>Profile Editor</li>\n</ul>\n<p>Note:  Currently, the test cases are scripted to run with only '<em>Required Email Verification</em>' flow.</p>\n<h3 id=\"whats-next\" style=\"position:relative;\"><a href=\"#whats-next\" aria-label=\"whats next permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What's next?</h3>\n<p>We are continuously working on improving this automation suite and soon we will be announcing the roadmap for automation suite.</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":"June 04, 2020","updated_date":null,"description":null,"title":"Automation for Identity Experience Framework is now open-source !!!","tags":["OpenSource","Automation"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7699115044247788,"src":"/static/51af1e97aec2b39f25f6184d64fe646c/58556/automation_ief.webp","srcSet":"/static/51af1e97aec2b39f25f6184d64fe646c/61e93/automation_ief.webp 200w,\n/static/51af1e97aec2b39f25f6184d64fe646c/1f5c5/automation_ief.webp 400w,\n/static/51af1e97aec2b39f25f6184d64fe646c/58556/automation_ief.webp 800w,\n/static/51af1e97aec2b39f25f6184d64fe646c/99238/automation_ief.webp 1200w,\n/static/51af1e97aec2b39f25f6184d64fe646c/135cd/automation_ief.webp 1280w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Sudhey Sharma","github":"sudheysharma","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":210,"currentPage":36,"type":"//engineering//","numPages":53,"pinned":"5c425581-f474-5ae9-abe7-cf5342db2aaa"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}