{"componentChunkName":"component---src-templates-blog-list-template-js","path":"/engineering/10","result":{"data":{"allMarkdownRemark":{"edges":[{"node":{"excerpt":"In this blog post, I will write a step-by-step tutorial to add Authentication to the Play Framework Application with OIDC and LoginRadius. I…","fields":{"slug":"/engineering/guest-post/add-authentication-to-play-framework-with-oidc-and-loginradius/"},"html":"<p>In this blog post, I will write a step-by-step tutorial to add Authentication to the Play Framework Application with OIDC and LoginRadius. I will be using <a href=\"http://www.pac4j.org/\">pac4j</a> and it's <a href=\"https://github.com/pac4j/play-pac4j\">play-pac4j</a> integration in this tutorial. Before jumping into the tutorial, let's learn about few concepts. </p>\n<h2 id=\"what-is-openid-connect-oidc-protocol\" style=\"position:relative;\"><a href=\"#what-is-openid-connect-oidc-protocol\" aria-label=\"what is openid connect oidc protocol permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 OpenID Connect (OIDC) Protocol?</h2>\n<p>OIDC is an authentication protocol that allows users to verify their identity when they are trying to access a protected HTTPS endpoint. OIDC is an evolutionary development of ideas implemented earlier in OAuth and OpenID.</p>\n<p>OpenID Connect allows clients to request and receive information about authenticated sessions and end-users. It allows all types of clients, including </p>\n<ul>\n<li>Web-based</li>\n<li>Mobile</li>\n<li>Javascript clients etc...</li>\n</ul>\n<p>You can find out more details about <a href=\"https://openid.net/connect/\">OIDC here</a></p>\n<h2 id=\"what-is-play-framework\" style=\"position:relative;\"><a href=\"#what-is-play-framework\" aria-label=\"what is play 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>What is Play Framework?</h2>\n<p>Play Framework is an open-source web application framework that follows the model–view–controller architectural pattern. It is written in Scala and usable from other programming languages that are compiled to JVM Bytecode.</p>\n<p>It makes it easy to build web applications with Java &#x26; Scala. Play is based on a lightweight, stateless, web-friendly architecture. Built on Akka, Play provides predictable and minimal resource consumption (CPU, memory, threads) for highly-scalable applications.</p>\n<h2 id=\"what-is-pac4j\" style=\"position:relative;\"><a href=\"#what-is-pac4j\" aria-label=\"what is pac4j permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 pac4j?</h2>\n<p><a href=\"http://www.pac4j.org/\">pac4j</a> is an easy and powerful security engine for Java to authenticate users, get their profiles and manage authorizations in order to secure web applications and web services.</p>\n<p>It provides a comprehensive set of concepts and components. It is based on Java and available under the Apache 2 license. It is available for most frameworks/tools and supports most authentication/authorization mechanisms.</p>\n<p>pac4j is supported with most of the Java frameworks like</p>\n<ul>\n<li>Spring Web MVC </li>\n<li>Spring Boot </li>\n<li>Spring Security (Spring Boot) </li>\n<li>Play 2.x </li>\n<li>Vertx Spark Java </li>\n<li>Javalin  </li>\n<li>Dropwizard </li>\n<li>Lagom </li>\n<li>Akka HTTP &#x26; many more...</li>\n</ul>\n<h2 id=\"getting-started\" style=\"position:relative;\"><a href=\"#getting-started\" aria-label=\"getting 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>Getting started</h2>\n<p>There are multiple options you can get started with the Play framework. </p>\n<ul>\n<li>You can create a new Play project by downloading the <a href=\"https://playframework.com/download#starters\">starter project here</a></li>\n<li>Create a new Play application using <code>sbt</code>.</li>\n</ul>\n<p>For this tutorial, I will be using creating a new play project using <code>sbt</code>.</p>\n<h3 id=\"install-sbt-on-mac-os\" style=\"position:relative;\"><a href=\"#install-sbt-on-mac-os\" aria-label=\"install sbt on mac os permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Install sbt on Mac OS</h3>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"console\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">brew install sbt</span></code></pre>\n<p>You can find <a href=\"https://www.scala-sbt.org/release/docs/Setup.html\">Installation steps for Windows and Linux</a> here.</p>\n<h3 id=\"prerequisites\" style=\"position:relative;\"><a href=\"#prerequisites\" aria-label=\"prerequisites permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Prerequisites</h3>\n<p>For this tutorial, I will be using </p>\n<ul>\n<li>Java 11</li>\n<li>sbt - 1.5.3</li>\n<li>play-pac4j - 11.0.0-PLAY2.8</li>\n<li>pac4j-oidc - 5.1.0</li>\n</ul>\n<h2 id=\"create-new-play-project\" style=\"position:relative;\"><a href=\"#create-new-play-project\" aria-label=\"create new play project permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create New Play Project</h2>\n<p>Create a new java play project using the following command</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"console\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">sbt new playframework/play-java-seed.g8</span></code></pre>\n<p>The above command will prompt you to fill in the project <code>name</code> and project package structure in <code>organization</code> as shown below.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"console\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">[info] welcome to sbt 1.5.3 (Oracle Corporation Java 11.0.2)</span>\n<span class=\"grvsc-line\">[info] set current project to new (in build file:/private/var/folders/_9/rcqwq2vx1cl_1sc4xdhb5_5c0000gn/T/sbt_661d1bf7/new/)</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">This template generates a Play Java project</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">name [play-java-seed]: loginradius-play-oidc</span>\n<span class=\"grvsc-line\">organization [com.example]: com.loginradius.developer</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">Template applied in /Users/vishnuchilamakuru/self/longinradius/./loginradius-play-oidc</span></code></pre>\n<h2 id=\"run-play-project\" style=\"position:relative;\"><a href=\"#run-play-project\" aria-label=\"run play project permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Run Play Project</h2>\n<p>Now that the project is created with a base template. You can test it by running the project using the following command from <code>loginradius-play-oidc</code> folder.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"console\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">sbt run</span></code></pre>\n<p>Now visit <code>http://localhost:9000</code>, and it should look like this.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 55.53846153846153%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAvUlEQVQoz+WPUQuDIBSF/f//bODDKBZNM22SL5WxoIiozlLWnlassbcdOFzRez/PJfx8AuUUqZaQUiFNJfLcwNY1rLVQN42IJUhkBiYUrkKCpwpsw6RtW3RdB1eHYUDf9xjH0d85YFVVvhZF4X1vGkzT5HvemcRxDCEElMpgjIHWGpcoQlmWmOfZD78Az/OeCeccYRgiCAIwxhawAqV0WTuHk4MeEdl7dLCjJlvR12Rr48cJ9377+crf6A+BD5SBXJjm2F2yAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"play-project-homepage.png\"\n        title=\"play-project-homepage.png\"\n        src=\"/static/98136bf03eb0d8319d556f6a7ba1237c/e5715/play-project-homepage.png\"\n        srcset=\"/static/98136bf03eb0d8319d556f6a7ba1237c/a6d36/play-project-homepage.png 650w,\n/static/98136bf03eb0d8319d556f6a7ba1237c/e5715/play-project-homepage.png 768w,\n/static/98136bf03eb0d8319d556f6a7ba1237c/ccf0c/play-project-homepage.png 1428w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h2 id=\"integrate-pac4j-with-play-project\" style=\"position:relative;\"><a href=\"#integrate-pac4j-with-play-project\" aria-label=\"integrate pac4j with play project permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Integrate pac4j with Play Project</h2>\n<h3 id=\"1-add-pac4j-dependencies-to-buildsbt\" style=\"position:relative;\"><a href=\"#1-add-pac4j-dependencies-to-buildsbt\" aria-label=\"1 add pac4j dependencies to buildsbt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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. Add pac4j dependencies to <code>build.sbt</code></h3>\n<p>Add pac4j dependencies, Java 11 as required, and target version to compile the project in <code>build.sbt</code>.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"scala\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">name := &quot;&quot;&quot;loginradius-play-oidc&quot;&quot;&quot;</span>\n<span class=\"grvsc-line\">organization := &quot;com.loginradius.developer&quot;</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">version := &quot;1.0-SNAPSHOT&quot;</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">lazy val root = (project in file(&quot;.&quot;)).enablePlugins(PlayJava)</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">scalaVersion := &quot;2.13.6&quot;</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">initialize := {</span>\n<span class=\"grvsc-line\">  val _ = initialize.value // run the previous initialization</span>\n<span class=\"grvsc-line\">  val required = &quot;11&quot;</span>\n<span class=\"grvsc-line\">  val current  = sys.props(&quot;java.specification.version&quot;)</span>\n<span class=\"grvsc-line\">  assert(current == required, s&quot;Unsupported JDK: java.specification.version $current != $required&quot;)</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">scalacOptions += &quot;-target:jvm-11&quot;</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">javacOptions ++= Seq(&quot;-source&quot;, &quot;11&quot;, &quot;-target&quot;, &quot;11&quot;)</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">libraryDependencies ++= Seq(</span>\n<span class=\"grvsc-line\">  guice,</span>\n<span class=\"grvsc-line\">  ehcache,</span>\n<span class=\"grvsc-line\">  &quot;org.pac4j&quot; %% &quot;play-pac4j&quot; % &quot;11.0.0-PLAY2.8&quot;,</span>\n<span class=\"grvsc-line\">  &quot;org.pac4j&quot; % &quot;pac4j-oidc&quot; % &quot;5.1.0&quot;,</span>\n<span class=\"grvsc-line\">  &quot;com.typesafe.play&quot; % &quot;play-cache_2.13&quot; % &quot;2.8.8&quot;,</span>\n<span class=\"grvsc-line\">  &quot;com.fasterxml.jackson.module&quot; %% &quot;jackson-module-scala&quot; % &quot;2.12.3&quot;</span>\n<span class=\"grvsc-line\">)</span></code></pre>\n<h3 id=\"2-create-security-module\" style=\"position:relative;\"><a href=\"#2-create-security-module\" aria-label=\"2 create security module permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. Create Security Module</h3>\n<p>Create <code>app/modules/SecurityModule.java</code>. This class configures OIDC, sets up a secure HttpActionAdapter, and registers callback and logout controllers.</p>\n<ul>\n<li>SecurityModule.java</li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"java\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">package</span><span class=\"mtk1\"> modules;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> com.google.inject.AbstractModule;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> com.nimbusds.oauth2.sdk.ParseException;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> com.typesafe.config.Config;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> net.minidev.json.JSONObject;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.core.authorization.authorizer.RequireAnyRoleAuthorizer;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.core.client.Clients;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.core.context.session.SessionStore;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.oidc.client.OidcClient;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.oidc.config.OidcConfiguration;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.play.CallbackController;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.play.LogoutController;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.play.http.PlayHttpActionAdapter;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.play.store.PlayCacheSessionStore;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> play.Environment;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> java.util.Optional;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">SecurityModule</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">AbstractModule</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Config</span><span class=\"mtk1\"> </span><span class=\"mtk12\">configuration</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk11\">SecurityModule</span><span class=\"mtk1\">(</span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Environment</span><span class=\"mtk1\"> </span><span class=\"mtk12\">environment</span><span class=\"mtk1\">, </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Config</span><span class=\"mtk1\"> </span><span class=\"mtk12\">configuration</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">configuration</span><span class=\"mtk1\"> = configuration;</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=\"mtk10\">Override</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">protected</span><span class=\"mtk1\"> </span><span class=\"mtk10\">void</span><span class=\"mtk1\"> </span><span class=\"mtk11\">configure</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">bind</span><span class=\"mtk1\">(</span><span class=\"mtk12\">SessionStore</span><span class=\"mtk1\">.</span><span class=\"mtk12\">class</span><span class=\"mtk1\">).</span><span class=\"mtk11\">to</span><span class=\"mtk1\">(</span><span class=\"mtk12\">PlayCacheSessionStore</span><span class=\"mtk1\">.</span><span class=\"mtk12\">class</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">OidcConfiguration</span><span class=\"mtk1\"> </span><span class=\"mtk12\">oidcConfiguration</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> </span><span class=\"mtk11\">OidcConfiguration</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">oidcConfiguration</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setDiscoveryURI</span><span class=\"mtk1\">(</span><span class=\"mtk12\">configuration</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getString</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;oidc.discoveryUri&quot;</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">oidcConfiguration</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setClientId</span><span class=\"mtk1\">(</span><span class=\"mtk12\">configuration</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getString</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;oidc.clientId&quot;</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">oidcConfiguration</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setSecret</span><span class=\"mtk1\">(</span><span class=\"mtk12\">configuration</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getString</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;oidc.clientSecret&quot;</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">oidcConfiguration</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setClientAuthenticationMethod</span><span class=\"mtk1\">(</span><span class=\"mtk12\">ClientAuthenticationMethod</span><span class=\"mtk1\">.</span><span class=\"mtk12\">CLIENT_SECRET_BASIC</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">addProviderMetadata</span><span class=\"mtk1\">(oidcConfiguration);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">OidcClient</span><span class=\"mtk1\"> </span><span class=\"mtk12\">oidcClient</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> </span><span class=\"mtk11\">OidcClient</span><span class=\"mtk1\">(oidcConfiguration);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">oidcClient</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addAuthorizationGenerator</span><span class=\"mtk1\">((ctx, session, profile) </span><span class=\"mtk4\">-&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">profile</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addRole</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;ROLE_ADMIN&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Optional</span><span class=\"mtk1\">.</span><span class=\"mtk11\">of</span><span class=\"mtk1\">(profile);</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\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">String</span><span class=\"mtk1\"> </span><span class=\"mtk12\">baseUrl</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">configuration</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getString</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;baseUrl&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Clients</span><span class=\"mtk1\"> </span><span class=\"mtk12\">clients</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Clients</span><span class=\"mtk1\">(baseUrl + </span><span class=\"mtk8\">&quot;/callback&quot;</span><span class=\"mtk1\">,  oidcClient);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">org</span><span class=\"mtk1\">.</span><span class=\"mtk10\">pac4j</span><span class=\"mtk1\">.</span><span class=\"mtk10\">core</span><span class=\"mtk1\">.</span><span class=\"mtk10\">config</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Config</span><span class=\"mtk1\"> </span><span class=\"mtk12\">config</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> org.pac4j.core.config.</span><span class=\"mtk11\">Config</span><span class=\"mtk1\">(clients);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">config</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addAuthorizer</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> </span><span class=\"mtk11\">RequireAnyRoleAuthorizer</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;ROLE_ADMIN&quot;</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">config</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setHttpActionAdapter</span><span class=\"mtk1\">(</span><span class=\"mtk12\">PlayHttpActionAdapter</span><span class=\"mtk1\">.</span><span class=\"mtk12\">INSTANCE</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">bind</span><span class=\"mtk1\">(</span><span class=\"mtk12\">org</span><span class=\"mtk1\">.</span><span class=\"mtk12\">pac4j</span><span class=\"mtk1\">.</span><span class=\"mtk12\">core</span><span class=\"mtk1\">.</span><span class=\"mtk12\">config</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Config</span><span class=\"mtk1\">.</span><span class=\"mtk12\">class</span><span class=\"mtk1\">).</span><span class=\"mtk11\">toInstance</span><span class=\"mtk1\">(config);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk3\">// callback</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">CallbackController</span><span class=\"mtk1\"> </span><span class=\"mtk12\">callbackController</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> </span><span class=\"mtk11\">CallbackController</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">callbackController</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setDefaultUrl</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">bind</span><span class=\"mtk1\">(</span><span class=\"mtk12\">CallbackController</span><span class=\"mtk1\">.</span><span class=\"mtk12\">class</span><span class=\"mtk1\">).</span><span class=\"mtk11\">toInstance</span><span class=\"mtk1\">(callbackController);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk3\">// logout</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">LogoutController</span><span class=\"mtk1\"> </span><span class=\"mtk12\">logoutController</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> </span><span class=\"mtk11\">LogoutController</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">logoutController</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setDefaultUrl</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/?defaulturlafterlogout&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">bind</span><span class=\"mtk1\">(</span><span class=\"mtk12\">LogoutController</span><span class=\"mtk1\">.</span><span class=\"mtk12\">class</span><span class=\"mtk1\">).</span><span class=\"mtk11\">toInstance</span><span class=\"mtk1\">(logoutController);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk10\">void</span><span class=\"mtk1\"> </span><span class=\"mtk11\">addProviderMetadata</span><span class=\"mtk1\">(</span><span class=\"mtk10\">OidcConfiguration</span><span class=\"mtk1\"> </span><span class=\"mtk12\">oidcConfiguration</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk10\">JSONObject</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jsonObj</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> </span><span class=\"mtk11\">JSONObject</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">jsonObj</span><span class=\"mtk1\">.</span><span class=\"mtk11\">appendField</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;token_endpoint&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">configuration</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getString</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;oidc.tokenUri&quot;</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">OIDCProviderMetadata</span><span class=\"mtk1\"> </span><span class=\"mtk12\">providerMetaData</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">try</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            providerMetaData = </span><span class=\"mtk12\">OIDCProviderMetadata</span><span class=\"mtk1\">.</span><span class=\"mtk11\">parse</span><span class=\"mtk1\">(jsonObj);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">oidcConfiguration</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setProviderMetadata</span><span class=\"mtk1\">(providerMetaData);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        } </span><span class=\"mtk15\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk10\">ParseException</span><span class=\"mtk1\"> </span><span class=\"mtk12\">e</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">e</span><span class=\"mtk1\">.</span><span class=\"mtk11\">printStackTrace</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<h3 id=\"3-create-secured-endpoint-in-controller\" style=\"position:relative;\"><a href=\"#3-create-secured-endpoint-in-controller\" aria-label=\"3 create secured endpoint in controller permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3. Create Secured Endpoint in Controller</h3>\n<p>In <code>app/controllers/HomeController.java</code> add the following methods</p>\n<ul>\n<li>A method that is secured by the OIDC client</li>\n<li>A method to show the profile information returned from LoginRadius(or any identity provider) on successful login.</li>\n<li>A method to get profile information</li>\n</ul>\n<p>After adding the above methods <code>HomeController.java</code> looks like this.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"java\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">package</span><span class=\"mtk1\"> controllers;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> com.google.inject.Inject;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.core.context.session.SessionStore;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.core.profile.ProfileManager;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.core.profile.UserProfile;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.play.context.PlayContextFactory;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.play.java.Secure;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.play.store.PlayCacheSessionStore;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> play.mvc.*;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> java.util.ArrayList;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> java.util.List;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">/**</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"> * This controller contains an action to handle HTTP requests</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"> * to the application&#39;s home page.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"> */</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">HomeController</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Controller</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">    /**</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">     * An action that renders an HTML page with a welcome message.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">     * The configuration in the &lt;code&gt;routes&lt;/code&gt; file means that</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">     * this method will be called when the application receives a</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">     * &lt;code&gt;GET&lt;/code&gt; request with a path of &lt;code&gt;/&lt;/code&gt;.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">     */</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Result</span><span class=\"mtk1\"> </span><span class=\"mtk11\">index</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\">ok</span><span class=\"mtk1\">(</span><span class=\"mtk12\">views</span><span class=\"mtk1\">.</span><span class=\"mtk12\">html</span><span class=\"mtk1\">.</span><span class=\"mtk12\">index</span><span class=\"mtk1\">.</span><span class=\"mtk11\">render</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=\"mtk10\">Secure</span><span class=\"mtk1\">(clients = </span><span class=\"mtk8\">&quot;OidcClient&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Result</span><span class=\"mtk1\"> </span><span class=\"mtk11\">oidcIndex</span><span class=\"mtk1\">(</span><span class=\"mtk10\">Http</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Request</span><span class=\"mtk1\"> </span><span class=\"mtk12\">req</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\">protectedIndex</span><span class=\"mtk1\">(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\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Result</span><span class=\"mtk1\"> </span><span class=\"mtk11\">protectedIndex</span><span class=\"mtk1\">(</span><span class=\"mtk10\">Http</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Request</span><span class=\"mtk1\"> </span><span class=\"mtk12\">req</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\">ok</span><span class=\"mtk1\">(</span><span class=\"mtk12\">views</span><span class=\"mtk1\">.</span><span class=\"mtk12\">html</span><span class=\"mtk1\">.</span><span class=\"mtk12\">protectedindex</span><span class=\"mtk1\">.</span><span class=\"mtk11\">render</span><span class=\"mtk1\">(</span><span class=\"mtk11\">getProfiles</span><span class=\"mtk1\">(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\">    @</span><span class=\"mtk10\">Inject</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk10\">SessionStore</span><span class=\"mtk1\"> </span><span class=\"mtk12\">sessionStore</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk10\">List</span><span class=\"mtk1\">&lt;</span><span class=\"mtk10\">UserProfile</span><span class=\"mtk1\">&gt; </span><span class=\"mtk11\">getProfiles</span><span class=\"mtk1\">(</span><span class=\"mtk10\">Http</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Request</span><span class=\"mtk1\"> </span><span class=\"mtk12\">req</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">ProfileManager</span><span class=\"mtk1\"> </span><span class=\"mtk12\">profileManager</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> </span><span class=\"mtk11\">ProfileManager</span><span class=\"mtk1\">(</span><span class=\"mtk12\">PlayContextFactory</span><span class=\"mtk1\">.</span><span class=\"mtk12\">INSTANCE</span><span class=\"mtk1\">.</span><span class=\"mtk11\">newContext</span><span class=\"mtk1\">(req), sessionStore);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">List</span><span class=\"mtk1\">&lt;</span><span class=\"mtk10\">UserProfile</span><span class=\"mtk1\">&gt; </span><span class=\"mtk12\">profiles</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">ArrayList</span><span class=\"mtk1\">&lt;&gt;();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">profileManager</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getProfile</span><span class=\"mtk1\">().</span><span class=\"mtk11\">isPresent</span><span class=\"mtk1\">()) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">profiles</span><span class=\"mtk1\">.</span><span class=\"mtk11\">add</span><span class=\"mtk1\">(</span><span class=\"mtk12\">profileManager</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getProfile</span><span class=\"mtk1\">().</span><span class=\"mtk11\">get</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\"> profiles;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<h3 id=\"4-create-views\" style=\"position:relative;\"><a href=\"#4-create-views\" aria-label=\"4 create views permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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. Create Views</h3>\n<ul>\n<li>Update <code>app/views/index.scala.html</code> as follows to add the link protected by OIDC authentication.</li>\n</ul>\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\">@()</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">@</span><span class=\"mtk11\">main</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Welcome to Play&quot;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Welcome to Play!</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;oidc/index.html&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Protected URL by OIDC</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></code></pre>\n<ul>\n<li>Add <code>app/views/protectedindex.scala.html</code> with the following content below. This page will be shown after Successful Login using OIDC in LoginRadius.</li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">@(</span><span class=\"mtk12\">profileList</span><span class=\"mtk1\">: </span><span class=\"mtk10\">java</span><span class=\"mtk1\">.</span><span class=\"mtk10\">util</span><span class=\"mtk1\">.</span><span class=\"mtk10\">List</span><span class=\"mtk1\">[</span><span class=\"mtk10\">org</span><span class=\"mtk1\">.</span><span class=\"mtk10\">pac4j</span><span class=\"mtk1\">.</span><span class=\"mtk10\">core</span><span class=\"mtk1\">.</span><span class=\"mtk10\">profile</span><span class=\"mtk1\">.</span><span class=\"mtk10\">UserProfile</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">@import scala.collection.JavaConverters._</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">@profiles() = { @profileList.</span><span class=\"mtk12\">toList</span><span class=\"mtk1\"> }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Protected Area</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><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;..&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Back</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">a</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">ul</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">li</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/logout?url=/?forcepostlogouturl&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;&lt;/</span><span class=\"mtk4\">li</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">ul</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\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    profiles: @profiles</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h3 id=\"5-configure-routes\" style=\"position:relative;\"><a href=\"#5-configure-routes\" aria-label=\"5 configure routes permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>5. Configure Routes</h3>\n<p>Now we already added methods in <code>HomeController.java</code> and configured callback, logout controllers in <code>SecurityModule.java</code>. Let's configure the routes to map to these methods in <code>conf/routes</code>.</p>\n<ul>\n<li><code>conf/routes</code> will look like this.</li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"scala\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"># Routes</span>\n<span class=\"grvsc-line\"># This file defines all application routes (Higher priority routes first)</span>\n<span class=\"grvsc-line\"># ~~~~</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"># An example controller showing a sample home page</span>\n<span class=\"grvsc-line\">GET     /                           controllers.HomeController.index</span>\n<span class=\"grvsc-line\">GET     /oidc/index.html            controllers.HomeController.oidcIndex(request: Request)</span>\n<span class=\"grvsc-line\">GET     /protected/index.html       controllers.HomeController.protectedIndex(request: Request)</span>\n<span class=\"grvsc-line\">GET     /callback                   @org.pac4j.play.CallbackController.callback(request: Request)</span>\n<span class=\"grvsc-line\">POST    /callback                   @org.pac4j.play.CallbackController.callback(request: Request)</span>\n<span class=\"grvsc-line\">GET     /logout                     @org.pac4j.play.LogoutController.logout(request: Request)</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"># Map static resources from the /public folder to the /assets URL path</span>\n<span class=\"grvsc-line\">GET     /assets/*file               controllers.Assets.versioned(path=&quot;/public&quot;, file: Asset)</span></code></pre>\n<h3 id=\"6-add-application-configuration-variables\" style=\"position:relative;\"><a href=\"#6-add-application-configuration-variables\" aria-label=\"6 add application configuration variables permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>6. Add Application Configuration variables</h3>\n<p>Finally, configure the variables mentioned in <code>SecurityModule.java</code> in <code>conf/application.conf</code> as follows.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"scala\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">play {</span>\n<span class=\"grvsc-line\">  modules {</span>\n<span class=\"grvsc-line\">    enabled += modules.SecurityModule</span>\n<span class=\"grvsc-line\">  }</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">baseUrl = &quot;http://localhost:9000&quot;</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">oidc.discoveryUri = &quot;https://cloud-api.loginradius.com/sso/oidc/v2/{loginradius-site-name}/{loginradius-app-name}/.well-known/openid-configuration&quot;</span>\n<span class=\"grvsc-line\">oidc.clientId = &quot;{clientId}&quot;</span>\n<span class=\"grvsc-line\">oidc.clientSecret = &quot;{clientSecret}&quot;</span>\n<span class=\"grvsc-line\">oidc.tokenUri = &quot;https://cloud-api.loginradius.com/sso/oidc/v2/{loginradius-site-name}/token&quot;</span></code></pre>\n<h2 id=\"create-an-oidc-app-in-loginradius\" style=\"position:relative;\"><a href=\"#create-an-oidc-app-in-loginradius\" aria-label=\"create an oidc app in 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>Create an OIDC app in LoginRadius</h2>\n<p>Login to your LoginRadius account or <a href=\"https://www.loginradius.com/\">signup here</a> if you don't have one. </p>\n<p>Once you log in you can see by default, one application will be created for you. Otherwise, you can create a new application here from the following screen by clicking <code>New App</code>.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 65.6923076923077%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAABR0lEQVQ4y61S2U7DMBDM/z+TNgJRrlQ9QQheeCj8DagFEXLbju0Mu27aRIiqQcLSyLs+ZmcP7272guXkGYvxivYVwut7TMcPhEdcnM8RDEL4wykGhMAPMfRvHPxghpNgjtOzBS5HS1yNFridPMGLdA1pDf5reXGS4fVtjfX6HUUpIKSEELQL2dgSUiporXvAwCvpMztSKVRV5aBU1doEvudV1/VReKzgt8WXaGCtdXBnR4i9ktKsO5+sJZt8TjtOEkJKdok8Lyh12QY7VEMmbKPu1AGSCDcfn9hEMQz527qKfgr3LFvDXbCaPM+RZjkKaoooS9ec3go5zUyZ/WNWk6QpFHWOgxljHP5EKHVbeFYYRV9ulHYkXOPehOg8qhtFP7vbtXs2pQXPYkF1q/Q2TQ7QnceDhLvOtWNj9woVDbs2pvFtr5S/AXDE7uVD3HNaAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"loginradius-dashboard.png\"\n        title=\"loginradius-dashboard.png\"\n        src=\"/static/19ce2c82b61d0cbc22b842b0b1158fb8/e5715/loginradius-dashboard.png\"\n        srcset=\"/static/19ce2c82b61d0cbc22b842b0b1158fb8/a6d36/loginradius-dashboard.png 650w,\n/static/19ce2c82b61d0cbc22b842b0b1158fb8/e5715/loginradius-dashboard.png 768w,\n/static/19ce2c82b61d0cbc22b842b0b1158fb8/78302/loginradius-dashboard.png 2798w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>I will be using the existing application itself for this demo as I am using a free plan. In the free plan, you can create only one application (no need for card details).</p>\n<p>Upgrade your application subscription to the <code>Developer Pro</code> Plan to configure OIDC. (<code>Developer Pro</code> Plan is available with 21 days trial).</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 77.6923076923077%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAABYlAAAWJQFJUiTwAAABxUlEQVQ4y41TWS8DURid/8cDsSRVRVCCSFpLI0UiEQ0SiQdC4okQ3iTibxAPlsT6JNZROtPZ7twe95vNVKfLl5y5y9x7vvMtVxpI5DDYvYyBrhySYkwmVhDrmEAilkJ/T8ZBb3wSna2jaGlKoqV5qCakJ7mI53wRPwUFZLLOYDAOlErgNgfnhBIaNUlVVRDy399QxCiYBFd1kAPbtmHzaEiKoqIg1L2+vePjU4am6y40H5oHd25ZVk2HkqsKTliBdwFGYLYXsgu6ELaahP5G6LjzJUWGYcAwTei6q1ItFmGKtX+vLIcUsp+bMEgl2frmFobH00hNZzGVncfswiImZ+awd3DkRcbLFRYUpaJSYbW51TW0x/swksrg4fEJX195ketPXF7fREYWEAY/Qt7IFpaW0dwWQ3IsjZfXt0D57d19fcKQxGB9fHKKje0d7O4f4uz8wlFGuKqnkMwWlZY1Bu4doPwYhgk6Y1g2LEaVZ86eKYpVl5CIdPFKwoS6qLAizpimFbQWkTIv9MZC9lom6ElB4M9JGXWG1YjCPypUEv5rbFpHEvp9GAUio4amkDWRN+7tW8IBpSCaMHh6vCqYo7RyP4rwF+S4sMVgf10uAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"loginradius-upgrade-subscription-1.png\"\n        title=\"loginradius-upgrade-subscription-1.png\"\n        src=\"/static/5c1a296411b3ae0135c3faddf34ac8a2/e5715/loginradius-upgrade-subscription-1.png\"\n        srcset=\"/static/5c1a296411b3ae0135c3faddf34ac8a2/a6d36/loginradius-upgrade-subscription-1.png 650w,\n/static/5c1a296411b3ae0135c3faddf34ac8a2/e5715/loginradius-upgrade-subscription-1.png 768w,\n/static/5c1a296411b3ae0135c3faddf34ac8a2/037ab/loginradius-upgrade-subscription-1.png 2274w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 69.6923076923077%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABYlAAAWJQFJUiTwAAAB+0lEQVQ4y42TzW8SQRiH+d8aNZrGphSs8WLSkxdj+eqys98CBT+uhpiiRxL16AWUiz1bOJF4EE1Mq12uWsTdhZ/vO8suUmgsyZN3Zph9+M3OSyK1uYtbmw+Qvnkft5MZbG3cw/qNO0hv7SCV3EFy4y6uX9vGlbUUrq6l/0tCMTQouoBpaXDKNqyHNvb3y6hUSjHVagXVWmVez8Pr1bIkUVSKUIhsNi+roRvQNI3QY4QQUFUh14XQ5DysIbquE4YkUSyqMIxIEop4QyijOY0dx0GpxGk5SQ212iNiXm3bhmmahBUKLcu6EP6xD4eH+HZ8gs+DLzg++Q53OMSp68J1h/hx6qJer8vUvF8KQ/synDRfKKDf7+Oiz8gLcNBoQKiqTLqU0IwqC+nI2VweH4+OMJ1O4fs+JpPJAp7noUFC9byQBQvimbBACbvdXvwwi/8VBkGwLIxSGSwxzFjIl6IoCrq9HgJ6+A8JfRJwUhbx2tjzVwhn6YRuSkIhzUmYy+XQIyFLfp2dYTQaScbjMb3BCTG9/JEZ3jgYDFZeyKefwOuvv3Hw4uWKSzHnkkhozG662Wyi0+mg1Wqh3W6jRXTev8OzV2+x+/wNHj95Su2lX65tuL+4dfjoTCaTicdirwBH3ZP7ohALR14FNzZ/z/8WPhLDYzknLNtZeGV/AY5b/JlWBK13AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"loginradius-upgrade-subscription-2.png\"\n        title=\"loginradius-upgrade-subscription-2.png\"\n        src=\"/static/6b180247c629f7ccad7e90c2f9568ef5/e5715/loginradius-upgrade-subscription-2.png\"\n        srcset=\"/static/6b180247c629f7ccad7e90c2f9568ef5/a6d36/loginradius-upgrade-subscription-2.png 650w,\n/static/6b180247c629f7ccad7e90c2f9568ef5/e5715/loginradius-upgrade-subscription-2.png 768w,\n/static/6b180247c629f7ccad7e90c2f9568ef5/52a2d/loginradius-upgrade-subscription-2.png 2534w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Now click on <code>Select &#x26; Configure</code> on your application and navigate to the <code>Integration</code> Section and Configure <code>Open ID</code> configuration. You can find step-by-step details to <a href=\"https://www.loginradius.com/developers/\">configure OIDC</a> here.</p>\n<p>Once you configure these <code>conf/application.conf</code> will look something like this.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"scala\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"># This is the main configuration file for the application.</span>\n<span class=\"grvsc-line\"># https://www.playframework.com/documentation/latest/ConfigFile</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">play {</span>\n<span class=\"grvsc-line\">  modules {</span>\n<span class=\"grvsc-line\">    enabled += modules.SecurityModule</span>\n<span class=\"grvsc-line\">  }</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">baseUrl = &quot;http://localhost:9000&quot;</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">oidc.discoveryUri = &quot;https://cloud-api.loginradius.com/sso/oidc/v2/dev-svv3qlcj2y/pac4j-play-loginradius-demo/.well-known/openid-configuration&quot;</span>\n<span class=\"grvsc-line\">oidc.clientId = &quot;8ce24413-9b7e-4282-9f5b-e0e5ec13a42a&quot;</span>\n<span class=\"grvsc-line\">oidc.clientSecret = &quot;c9c61f6e-325f-40d6-89fd-696d17f970eb&quot;</span>\n<span class=\"grvsc-line\">oidc.tokenUri = &quot;https://cloud-api.loginradius.com/sso/oidc/v2/dev-svv3qlcj2y/token&quot;</span>\n<span class=\"grvsc-line\"># Site Name - dev-svv3qlcj2y</span>\n<span class=\"grvsc-line\"># App Name - pac4j-play-loginradius-demo</span></code></pre>\n<h2 id=\"time-to-test-complete-integration\" style=\"position:relative;\"><a href=\"#time-to-test-complete-integration\" aria-label=\"time to test complete 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>Time to test complete Integration</h2>\n<p>Let's run our application using <code>sbt clean run</code> and visit <code>http://localhost:9000</code>. The Home page will look like this.</p>\n<h3 id=\"home-page\" style=\"position:relative;\"><a href=\"#home-page\" aria-label=\"home page permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Home Page</h3>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 27.692307692307693%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAbUlEQVQY062OwQqAIBBE9/8/0OoUdRbRrURDncxTWERCAw922WF5JKWE1hpKKRhjYJixrGuZnfOIMSKEkIkv5PvZ2xjUdwOmcYYQojytk1L6Tu6T5R2WPcr28KApuU+1SbNVBd2MEtrNLiH8nAPPEtpLdJBSVwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"home-page.png\"\n        title=\"home-page.png\"\n        src=\"/static/a6ab822950175d12e45d43fb76ca2967/e5715/home-page.png\"\n        srcset=\"/static/a6ab822950175d12e45d43fb76ca2967/a6d36/home-page.png 650w,\n/static/a6ab822950175d12e45d43fb76ca2967/e5715/home-page.png 768w,\n/static/a6ab822950175d12e45d43fb76ca2967/cbe7f/home-page.png 2420w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h3 id=\"loginradius-auth-page-idx\" style=\"position:relative;\"><a href=\"#loginradius-auth-page-idx\" aria-label=\"loginradius auth page idx permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>LoginRadius Auth Page (IDX)</h3>\n<p>Now click on the <code>protected url by OIDC</code> link on the home page that will redirect you to the LoginRadius Auth Page (IDX), which you configured.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 61.07692307692307%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABYlAAAWJQFJUiTwAAACXElEQVQoz3WTS2sTURiGTyZp00xm0twvzT12YhNTklJrIdWFBcG0tQ2Iim5EV/4CEaRidaNQxdpYRS2oUFsEXYvtxp0L9+5FdC8o2pY8nkmaNqG4ePnOZXjO+57vjKhUJqhWq5yanGB8fJyxcpmZyQqXzk5TvbXG6FsYW/1Nee0v5dU/jTpmjqWOyflRc/5mm5HVTUZXfiH8/gDRaAy/z4ewWLFZFdKZDIV0BP3MXcQSiPltxH3+r3tt41A4gsXahcOpo2k6Q0NFSsMjJHwq2sxNLMtgXdhEWayj1OqNKh52ytK+ZxhZNN0lgS7cmkoyHsUXDOHpFhI4h3guT32whWiAJLwGh1aaKkilXoBNrpl7YlEql8uTDAexKDZ6dR2fy0kkFifh1/Cek5GfyY8WWkDTCRiv6mSl0i9Bf2I6bAMOHz7CUKlEKpXkQCpByKMRlA5TAQ11anafQzNaSK55nkLPUh31sVnbgANGP/FohICnl7DbyaCRJhTw4xAC+8lriGUTuLkLNCGvv2zx8Vudja/w6UedO5/NFDvAWMiHX+/BZVfQe2xk+oIU+1NkPQq+03P7ItsewYUPcHkDzr+vc3Edjr9rc1gsFkj2hXGrXbgcXSQScYysQS7owDl9Yy+y2dHF5thyZR1x+zvCbMZ8vflcWvdYyB3EiIUbLt0OG1EJTOULqDKytTK7F7kFNJ/J/E8U8ynVmnfa0ZRSfoCIW8Wr2fFIl25dJZ/PE7YLLCeudgJb0Bq7cNEOMzUoHfolLKB3E+p1EPG6yMg/xfAqOKeu70TudNgBb9Ud/QNovwJ4rzBaFgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"loginradius-consent-page.png\"\n        title=\"loginradius-consent-page.png\"\n        src=\"/static/2c30cb2b6ecd675ee7f6adecae33022c/e5715/loginradius-consent-page.png\"\n        srcset=\"/static/2c30cb2b6ecd675ee7f6adecae33022c/a6d36/loginradius-consent-page.png 650w,\n/static/2c30cb2b6ecd675ee7f6adecae33022c/e5715/loginradius-consent-page.png 768w,\n/static/2c30cb2b6ecd675ee7f6adecae33022c/0bd07/loginradius-consent-page.png 2898w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h3 id=\"redirect-to-protected-index-page\" style=\"position:relative;\"><a href=\"#redirect-to-protected-index-page\" aria-label=\"redirect to protected index 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>Redirect to Protected Index Page</h3>\n<p>On successful login from the above step, you will be redirected to the <code>protectedindex.scala.html</code> page.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 27.53846153846154%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAAArklEQVQY062QfQuDIBDG/f5fr3ctwhq0P4KVrazcfKYHQg3GGEz48Tzn6Z0eq+saXXfFPE1Y1Ih5HEh3vcDuG57bkRUPp+ausLlzel3RqxnDrcekFEZ3j+lFwxiDfy0muIAQAlmWEUVRgHOOPM/JH5FS4tK2pE3TEFIGlWhdjkVRhDiOkSQJEbwv7jVN09N+WZbUsKoq+HH5OOCLMmvt6cnH2Pv3/Ncv/zqj0OQTL9GMyioWc8KWAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"loginradius-protected-index-page.png\"\n        title=\"loginradius-protected-index-page.png\"\n        src=\"/static/d83ff98f9f5a31ea8e23d98a8cc079e4/e5715/loginradius-protected-index-page.png\"\n        srcset=\"/static/d83ff98f9f5a31ea8e23d98a8cc079e4/a6d36/loginradius-protected-index-page.png 650w,\n/static/d83ff98f9f5a31ea8e23d98a8cc079e4/e5715/loginradius-protected-index-page.png 768w,\n/static/d83ff98f9f5a31ea8e23d98a8cc079e4/8c565/loginradius-protected-index-page.png 3346w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h3 id=\"logout-action\" style=\"position:relative;\"><a href=\"#logout-action\" aria-label=\"logout action permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Logout Action</h3>\n<p><a href=\"https://github.com/pac4j/play-pac4j\">play-pac4j</a> provides out of the box <code>LogoutController</code> which can be used to handle logout flows. It has <code>logout</code> functionality which has the logout logic implementation to clear the session. Below is the sample <code>logout</code> functionality from <code>org.pac4j.play.LogoutController</code> play-pac4j module.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"java\" data-index=\"12\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk10\">CompletionStage</span><span class=\"mtk1\">&lt;Result&gt; </span><span class=\"mtk11\">logout</span><span class=\"mtk1\">(</span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Http</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Request</span><span class=\"mtk1\"> request) {</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">HttpActionAdapter</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bestAdapter</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">FindBest</span><span class=\"mtk1\">.</span><span class=\"mtk11\">httpActionAdapter</span><span class=\"mtk1\">(</span><span class=\"mtk4\">null</span><span class=\"mtk1\">, config, </span><span class=\"mtk12\">PlayHttpActionAdapter</span><span class=\"mtk1\">.</span><span class=\"mtk12\">INSTANCE</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">LogoutLogic</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bestLogic</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">FindBest</span><span class=\"mtk1\">.</span><span class=\"mtk11\">logoutLogic</span><span class=\"mtk1\">(logoutLogic, config, </span><span class=\"mtk12\">DefaultLogoutLogic</span><span class=\"mtk1\">.</span><span class=\"mtk12\">INSTANCE</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">WebContext</span><span class=\"mtk1\"> </span><span class=\"mtk12\">context</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">FindBest</span><span class=\"mtk1\">.</span><span class=\"mtk11\">webContextFactory</span><span class=\"mtk1\">(</span><span class=\"mtk4\">null</span><span class=\"mtk1\">, config, </span><span class=\"mtk12\">PlayContextFactory</span><span class=\"mtk1\">.</span><span class=\"mtk12\">INSTANCE</span><span class=\"mtk1\">).</span><span class=\"mtk11\">newContext</span><span class=\"mtk1\">(request);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">CompletableFuture</span><span class=\"mtk1\">.</span><span class=\"mtk11\">supplyAsync</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">-&gt;</span><span class=\"mtk1\"> (Result) </span><span class=\"mtk12\">bestLogic</span><span class=\"mtk1\">.</span><span class=\"mtk11\">perform</span><span class=\"mtk1\">(context, sessionStore, config, bestAdapter, </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">defaultUrl</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">logoutUrlPattern</span><span class=\"mtk1\">, </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">localLogout</span><span class=\"mtk1\">, </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">destroySession</span><span class=\"mtk1\">, </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">centralLogout</span><span class=\"mtk1\">), </span><span class=\"mtk12\">ec</span><span class=\"mtk1\">.</span><span class=\"mtk11\">current</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span></code></pre>\n<p>So to use this LogoutController, we just need to initialize it and define logout route for the same in our <code>routes</code>. We already initialized LoginController in <code>SecurityModule.java</code>.</p>\n<h4 id=\"a-initialize-logoutcontroller\" style=\"position:relative;\"><a href=\"#a-initialize-logoutcontroller\" aria-label=\"a initialize logoutcontroller permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>a. Initialize LogoutController</h4>\n<ul>\n<li>You can configure default url which application needs to redirect after <code>logout</code> action.</li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"java\" data-index=\"13\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">// logout</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">LogoutController</span><span class=\"mtk1\"> </span><span class=\"mtk12\">logoutController</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> </span><span class=\"mtk11\">LogoutController</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">logoutController</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setDefaultUrl</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/?defaulturlafterlogout&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">bind</span><span class=\"mtk1\">(</span><span class=\"mtk12\">LogoutController</span><span class=\"mtk1\">.</span><span class=\"mtk12\">class</span><span class=\"mtk1\">).</span><span class=\"mtk11\">toInstance</span><span class=\"mtk1\">(logoutController);</span></span></code></pre>\n<h4 id=\"b-define-route-for-logoutcontroller\" style=\"position:relative;\"><a href=\"#b-define-route-for-logoutcontroller\" aria-label=\"b define route for logoutcontroller permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>b. Define Route for LogoutController</h4>\n<ul>\n<li>We already configured <code>/logout</code> Route using <code>LogoutController</code> in <code>conf/routes</code>.</li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"scala\" data-index=\"14\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">GET     /logout                     @org.pac4j.play.LogoutController.logout(request: Request)</span></code></pre>\n<p>On Clicking <code>logout</code> in our application, the session will be cleared and you will be redirected to the Home page based on our configuration. </p>\n<h2 id=\"source-code\" style=\"position:relative;\"><a href=\"#source-code\" aria-label=\"source code permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Source Code</h2>\n<p>You can see the full source code for the application developed in this tutorial on <a href=\"https://github.com/vishnuchilamakuru/loginradius-play-oidc-example\">GitHub</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 .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk17 { color: #808080; }\n</style>","frontmatter":{"date":"June 25, 2021","updated_date":null,"description":"Learn how to integrate play-pac4j and use its OIDC support to authenticate with LoginRadius using JAVA play framework.","title":"Add Authentication to Play Framework With OIDC and LoginRadius","tags":["OIDC","Java","pac4j","Play Framework","Authentication"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/7fda86ee912dfb6374d4838c3062813c/ee604/pac4j-authentication.png","srcSet":"/static/7fda86ee912dfb6374d4838c3062813c/69585/pac4j-authentication.png 200w,\n/static/7fda86ee912dfb6374d4838c3062813c/497c6/pac4j-authentication.png 400w,\n/static/7fda86ee912dfb6374d4838c3062813c/ee604/pac4j-authentication.png 800w,\n/static/7fda86ee912dfb6374d4838c3062813c/db955/pac4j-authentication.png 900w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Vishnu Chilamakuru","github":"vishnuchilamakuru","avatar":null}}}},{"node":{"excerpt":"There is an advanced feature of React that it can write renderers for multiple different env. Let discuss a few of them. React-Figma This is…","fields":{"slug":"/engineering/react-renderer/"},"html":"<p>There is an advanced feature of React that it can write renderers for multiple different env. Let discuss a few of them.</p>\n<h2 id=\"react-figma\" style=\"position:relative;\"><a href=\"#react-figma\" aria-label=\"react figma permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><a href=\"https://github.com/react-figma/react-figma\" title=\"React-Figma\">React-Figma</a></h2>\n<p>This is a Renderer for Figma. It can use React components as a design source.</p>\n<p>Sample code with react-figma:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk4\">*</span><span class=\"mtk1\"> </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> </span><span class=\"mtk12\">React</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;react&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Page</span><span class=\"mtk1\">, </span><span class=\"mtk12\">View</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Text</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;react-figma&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">App</span><span class=\"mtk1\"> = () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Page</span><span class=\"mtk1\"> </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;My Resume&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">isCurrent</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">View</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">View</span><span class=\"mtk1\"> </span><span class=\"mtk12\">style</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">{ </span><span class=\"mtk12\">width:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">200</span><span class=\"mtk1\">, </span><span class=\"mtk12\">height:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">100</span><span class=\"mtk1\">, </span><span class=\"mtk12\">backgroundColor:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;#dd423a&#39;</span><span class=\"mtk1\"> }</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span><span class=\"mtk1\">                </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Text</span><span class=\"mtk1\"> </span><span class=\"mtk12\">style</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">{ </span><span class=\"mtk12\">color:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;white&#39;</span><span class=\"mtk1\"> }</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Hi, There</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Text</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">View</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Page</span><span class=\"mtk17\">&gt;</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>Nowadays, Figma is the most popular design tool,  similar renderers available as well: <code>react-sketchapp</code> for Sketch, <code>react-x</code>d for Adobe XD.</p>\n<h2 id=\"react-hardware\" style=\"position:relative;\"><a href=\"#react-hardware\" aria-label=\"react hardware permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><a href=\"https://github.com/iamdustan/react-hardware\" title=\"React Hardware\">React Hardware</a></h2>\n<p>A device like Arduino can be operated by React components. </p>\n<p>Let's checkout demo code :</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">React</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;react&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">ReactHardware</span><span class=\"mtk1\">, {</span><span class=\"mtk12\">Led</span><span class=\"mtk1\">} </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;react-hardware&#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=\"mtk11\">App</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\">ledStage</span><span class=\"mtk1\">, </span><span class=\"mtk12\">setLedStage</span><span class=\"mtk1\">] = </span><span class=\"mtk11\">useState</span><span class=\"mtk1\">(</span><span class=\"mtk4\">false</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">useEffect</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">setInterval</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">setLedStage</span><span class=\"mtk1\">(</span><span class=\"mtk12\">prev</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> !</span><span class=\"mtk12\">prev</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }, </span><span class=\"mtk7\">2000</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }, []);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Led</span><span class=\"mtk1\"> </span><span class=\"mtk12\">pin</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk7\">13</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">ledStage</span><span class=\"mtk1\"> ? </span><span class=\"mtk7\">255</span><span class=\"mtk1\"> : </span><span class=\"mtk7\">0</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\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=\"mtk8\">&#39;dev/tty.usbmodem1411&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">ReactHardware</span><span class=\"mtk1\">.</span><span class=\"mtk11\">render</span><span class=\"mtk1\">(</span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">App</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">PORT</span><span class=\"mtk1\">);</span></span></code></pre>\n<h2 id=\"ink\" style=\"position:relative;\"><a href=\"#ink\" aria-label=\"ink permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><a href=\"https://github.com/vadimdemedes/ink\" title=\"Ink\">Ink</a></h2>\n<p>Another React solution for CLIs. It allows you to run, build and test your CLI output through components:</p>\n<p>The code of the demo:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Raiser</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\">i</span><span class=\"mtk1\">, </span><span class=\"mtk12\">setI</span><span class=\"mtk1\">] = </span><span class=\"mtk11\">useState</span><span class=\"mtk1\">(</span><span class=\"mtk7\">0</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">useEffect</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">setInterval</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">setI</span><span class=\"mtk1\">(</span><span class=\"mtk12\">prev</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">prev</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=\"mtk7\">200</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }, []);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Color</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    Increased by </span><span class=\"mtk4\">{</span><span class=\"mtk12\">i</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Color</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Ink is a popular one that is used by libraries such a Gatsby, Parcel, Yarn 2, etc.\n<code>react-blessed</code> is one of the similar libraries.</p>\n<h2 id=\"react-three-fiber\" style=\"position:relative;\"><a href=\"#react-three-fiber\" aria-label=\"react three fiber permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><a href=\"https://github.com/pmndrs/react-three-fiber\" title=\"react-three-fiber\">react-three-fiber</a></h2>\n<p>This is a great  React renderer for threejs on the react-native and web.</p>\n<p>Let's see a sample code:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">ReactDOM</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;react-dom&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">React</span><span class=\"mtk1\">, { </span><span class=\"mtk12\">useRef</span><span class=\"mtk1\">, </span><span class=\"mtk12\">useState</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;react&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">Canvas</span><span class=\"mtk1\">, </span><span class=\"mtk12\">useFrame</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;react-three-fiber&#39;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">MyFrame</span><span class=\"mtk1\">(</span><span class=\"mtk12\">props</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\">Ref</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">useRef</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\">hover</span><span class=\"mtk1\">, </span><span class=\"mtk12\">setOnHover</span><span class=\"mtk1\">] = </span><span class=\"mtk11\">useState</span><span class=\"mtk1\">(</span><span class=\"mtk4\">false</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">enable</span><span class=\"mtk1\">, </span><span class=\"mtk12\">setEnable</span><span class=\"mtk1\">] = </span><span class=\"mtk11\">useState</span><span class=\"mtk1\">(</span><span class=\"mtk4\">false</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">useFrame</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">Ref</span><span class=\"mtk1\">.</span><span class=\"mtk12\">current</span><span class=\"mtk1\">.</span><span class=\"mtk12\">rotation</span><span class=\"mtk1\">.</span><span class=\"mtk12\">x</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">Ref</span><span class=\"mtk1\">.</span><span class=\"mtk12\">current</span><span class=\"mtk1\">.</span><span class=\"mtk12\">rotation</span><span class=\"mtk1\">.</span><span class=\"mtk12\">y</span><span class=\"mtk1\"> += </span><span class=\"mtk7\">0.01</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Ref</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">{</span><span class=\"mtk1\">...</span><span class=\"mtk12\">props</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">ref</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">Ref</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">scale</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">enable</span><span class=\"mtk1\"> ? [</span><span class=\"mtk7\">1.5</span><span class=\"mtk1\">, </span><span class=\"mtk7\">1.5</span><span class=\"mtk1\">, </span><span class=\"mtk7\">1.5</span><span class=\"mtk1\">] : [</span><span class=\"mtk7\">1</span><span class=\"mtk1\">, </span><span class=\"mtk7\">1</span><span class=\"mtk1\">, </span><span class=\"mtk7\">1</span><span class=\"mtk1\">]</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">onClick</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk11\">setEnable</span><span class=\"mtk1\">(!</span><span class=\"mtk12\">enable</span><span class=\"mtk1\">)</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">onPointerOver</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk11\">setOnHover</span><span class=\"mtk1\">(</span><span class=\"mtk4\">true</span><span class=\"mtk1\">)</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">onPointerOut</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk11\">setOnHover</span><span class=\"mtk1\">(</span><span class=\"mtk4\">false</span><span class=\"mtk1\">)</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">boxBufferGeometry</span><span class=\"mtk1\"> </span><span class=\"mtk12\">args</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">[</span><span class=\"mtk7\">1</span><span class=\"mtk1\">, </span><span class=\"mtk7\">1</span><span class=\"mtk1\">, </span><span class=\"mtk7\">1</span><span class=\"mtk1\">]</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">meshStandardMaterial</span><span class=\"mtk1\"> </span><span class=\"mtk12\">color</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">hover</span><span class=\"mtk1\"> ? </span><span class=\"mtk8\">&#39;hotpink&#39;</span><span class=\"mtk1\"> : </span><span class=\"mtk8\">&#39;orange&#39;</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Ref</span><span class=\"mtk17\">&gt;</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\">ReactDOM</span><span class=\"mtk1\">.</span><span class=\"mtk11\">render</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Canvas</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">pointLight</span><span class=\"mtk1\"> </span><span class=\"mtk12\">position</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">[</span><span class=\"mtk7\">10</span><span class=\"mtk1\">, </span><span class=\"mtk7\">10</span><span class=\"mtk1\">, </span><span class=\"mtk7\">10</span><span class=\"mtk1\">]</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">MyFrame</span><span class=\"mtk1\"> </span><span class=\"mtk12\">position</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">[-</span><span class=\"mtk7\">3.2</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=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">MyFrame</span><span class=\"mtk1\"> </span><span class=\"mtk12\">position</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">[</span><span class=\"mtk7\">2.2</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=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Canvas</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getElementById</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;root&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">)</span></span></code></pre>\n<p>The library has a great ecosystem along with packages such as <code>react-three-flex</code> ,<code>react-xr</code>, <code>react-postprocessing</code> , etc.</p>\n<h2 id=\"react-nil\" style=\"position:relative;\"><a href=\"#react-nil\" aria-label=\"react nil permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><a href=\"https://github.com/pmndrs/react-nil\" title=\"react-nil\">react-nil</a></h2>\n<p>A renderer for React that render nothing.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">React</span><span class=\"mtk1\">, { </span><span class=\"mtk12\">useState</span><span class=\"mtk1\">, </span><span class=\"mtk12\">useEffect</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;react&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">render</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;react-nil&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">MyComponent</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\">active</span><span class=\"mtk1\">, </span><span class=\"mtk12\">set</span><span class=\"mtk1\">] = </span><span class=\"mtk11\">useState</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=\"mtk11\">useEffect</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk4\">void</span><span class=\"mtk1\"> </span><span class=\"mtk11\">setInterval</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk11\">set</span><span class=\"mtk1\">((</span><span class=\"mtk12\">active</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> !</span><span class=\"mtk12\">active</span><span class=\"mtk1\">), </span><span class=\"mtk7\">1000</span><span class=\"mtk1\">), [])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">null</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">render</span><span class=\"mtk1\">(</span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">MyComponent</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span><span class=\"mtk1\">)</span></span></code></pre>\n<p>It provides you kind of high-level abstraction to Node.</p>\n<h2 id=\"react-docx\" style=\"position:relative;\"><a href=\"#react-docx\" aria-label=\"react docx permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><a href=\"https://github.com/Jeday/react-docx\" title=\"react-docx\">react-docx</a></h2>\n<p>Another reconciler for DOCX.js. </p>\n<p>Let's understand with a sample code:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">renderAsyncDocument</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">section</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">paragraph</span><span class=\"mtk1\"> </span><span class=\"mtk12\">heading</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">Docx</span><span class=\"mtk1\">.</span><span class=\"mtk12\">HeadingLevel</span><span class=\"mtk1\">.</span><span class=\"mtk12\">HEADING_1</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      This is a sample paragraph with paragraph tag</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">paragraph</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\">      This is a sample paragraph with P tag</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\">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\">t</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">this is for textrun</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">t</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\">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\">img</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">src</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;base64....&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">width</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk7\">200</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">height</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk7\">200</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">href</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">src</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;http://localhost:8080&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">label</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk8\">&quot;image n links label&quot;</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Component</span><span class=\"mtk1\"> </span><span class=\"mtk12\">text</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;can try componets in this way of course, like react!&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Component</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">section</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">).</span><span class=\"mtk11\">then</span><span class=\"mtk1\">((</span><span class=\"mtk12\">doc</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">doc</span><span class=\"mtk1\">));</span></span></code></pre>\n<p>Also, you can checkout  <code>react-pdf</code> and <code>redocx</code> for a similar purpose.</p>\n<p>Can visit this <a href=\"https://github.com/chentsulin/awesome-react-renderer\" title=\"Github Repo\">Github Repo</a> for a curated list of react renderers.</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 .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk17 { color: #808080; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n</style>","frontmatter":{"date":"June 23, 2021","updated_date":null,"description":"There is an advanced feature of React is that it can write renderers for multiple different env.","title":"React renderers, react everywhere?","tags":["JavaScript","React","Renderer"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/3e300a00ec9a7919e0e181600a6fc755/ee604/react.png","srcSet":"/static/3e300a00ec9a7919e0e181600a6fc755/69585/react.png 200w,\n/static/3e300a00ec9a7919e0e181600a6fc755/497c6/react.png 400w,\n/static/3e300a00ec9a7919e0e181600a6fc755/ee604/react.png 800w,\n/static/3e300a00ec9a7919e0e181600a6fc755/f3583/react.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Abhimanyu Singh Rathore","github":"abhir9","avatar":null}}}},{"node":{"excerpt":"React's Context API Guide with Example In this blog, You will learn What React's Context API is and how to use React's Context API. It is…","fields":{"slug":"/engineering/react-context-api-guide-with-example/"},"html":"<h1 id=\"reacts-context-api-guide-with-example\" style=\"position:relative;\"><a href=\"#reacts-context-api-guide-with-example\" aria-label=\"reacts context api guide with example permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>React's Context API Guide with Example</h1>\n<p>In this blog, You will learn What React's Context API is and how to use React's Context API. It is very much used as a state management tool, oftentimes replacing Redux.<br>\nAccording to the React doc: </p>\n<blockquote>\n<p>Context provides a way to pass data through the component tree\nwithout having to pass props down manually at every level.</p>\n</blockquote>\n<p>To be more clear, this provides a way for you to make values available to all components of your application, no matter how complicated your application is.</p>\n<h2 id=\"when-to-use-context\" style=\"position:relative;\"><a href=\"#when-to-use-context\" aria-label=\"when to use context permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>When to use context</h2>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">App</span><span class=\"mtk1\"> = () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">ParentClass</span><span class=\"mtk1\"> </span><span class=\"mtk12\">color</span><span class=\"mtk1\">= </span><span class=\"mtk8\">&quot;blue&quot;</span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">ParentClass</span><span class=\"mtk1\"> = (</span><span class=\"mtk12\">props</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=\"mtk17\">&lt;</span><span class=\"mtk10\">ChildClass</span><span class=\"mtk1\"> </span><span class=\"mtk12\">color</span><span class=\"mtk1\">= </span><span class=\"mtk4\">{</span><span class=\"mtk12\">props</span><span class=\"mtk1\">.</span><span class=\"mtk12\">color</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">ChildClass</span><span class=\"mtk1\"> = (</span><span class=\"mtk12\">props</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=\"mtk17\">&lt;</span><span class=\"mtk10\">GrandChildClass</span><span class=\"mtk1\"> </span><span class=\"mtk12\">color</span><span class=\"mtk1\">= </span><span class=\"mtk4\">{</span><span class=\"mtk12\">props</span><span class=\"mtk1\">.</span><span class=\"mtk12\">color</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">GrandChildClass</span><span class=\"mtk1\"> = (</span><span class=\"mtk12\">props</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=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Color: </span><span class=\"mtk4\">{</span><span class=\"mtk12\">props</span><span class=\"mtk1\">.</span><span class=\"mtk12\">color</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">)</span></span></code></pre>\n<p>In the above code, we designed the application in which used color props in the ParentClass and passed that props to all component (top to down) without checking that it is required by the child class or not and another issue also here that in case if GrandChildClass component was more deeply nested than it was very difficult to manage. This is the problem that <code>Context</code> solves. Context is designed the share values that can be considered \"global\" such as preferred language, current user, or theme. </p>\n<p>Using context, we can avoid passing props. Let's create the above example code using context:</p>\n<p>We will create a separate component for context that we can use throughout the components.\nOnce you have initialized your project, create a file called ColorContext.js in your <code>/src</code> folder.</p>\n<h3 id=\"create-context\" style=\"position:relative;\"><a href=\"#create-context\" aria-label=\"create context permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create Context</h3>\n<p>Using React.createContext, we can create context and pass anything as an argument to <code>React.createContext</code>. In our case, we are passing \"white\" color to provide a light theme.</p>\n<p>This will also give me  <code>ColorContext.Provider</code>  and  <code>ColorContext.Consumer</code>. What these two components do is straightforward:</p>\n<ul>\n<li><strong>Provider</strong>  - The component that provides the value</li>\n<li><strong>Consumer</strong>  - A component that is consuming the value</li>\n<li>\n<p>import React from \"react\";</p>\n<p>const ColorContext = React.createContext(\"white\");\nexport default ColorContext;</p>\n</li>\n</ul>\n<p>To use this context all over the components, we have to use the provider. According to React document, every context object comes with a Provider React component that allows consuming components to subscribe to context changes.</p>\n<h3 id=\"providing-context\" style=\"position:relative;\"><a href=\"#providing-context\" aria-label=\"providing context permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Providing Context</h3>\n<p>After successfully creating context, we can import context and use it to create our provider.\nAs we want to access context in the entire application, we need to wrap our app in <code>ColorContext.Provider</code>.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">ColorContext</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./ColorContext&#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=\"mtk11\">App</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\">color</span><span class=\"mtk1\">= </span><span class=\"mtk8\">&quot;white&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">ColorContext.Provider</span><span class=\"mtk1\"> </span><span class=\"mtk12\">value</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">{</span><span class=\"mtk12\">color</span><span class=\"mtk4\">}</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\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;App&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\">header</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;App-header&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\">img</span><span class=\"mtk1\"> </span><span class=\"mtk12\">src</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">logo</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;App-logo&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">alt</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;logo&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;App-title&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Welcome to my web page</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">header</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">ColorContext.Provider</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span></code></pre>\n<h3 id=\"consuming-the-context\" style=\"position:relative;\"><a href=\"#consuming-the-context\" aria-label=\"consuming the context permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Consuming the context</h3>\n<p>The approach to providing context is the same for class and functional components but consuming is a little different for both.</p>\n<h4 id=\"class-component\" style=\"position:relative;\"><a href=\"#class-component\" aria-label=\"class component permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>class component</h4>\n<p>Mainly used way to accessing context in class component using static <code>contextType</code>. After that, you can access the context value using <code>this.context</code>.  You can refer to it in any lifecycle method and even in the render method.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">ColorContext</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./ColorContext&#39;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Page</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Component</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">static</span><span class=\"mtk1\"> </span><span class=\"mtk12\">contextType</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">ColorContext</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">componentDidMount</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\">colorValue</span><span class=\"mtk1\">= </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">context</span></span>\n<span class=\"grvsc-line\"></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\">colorValue</span><span class=\"mtk1\">) </span><span class=\"mtk3\">//  &quot;white&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=\"mtk11\">render</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=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Color Value is </span><span class=\"mtk4\">{</span><span class=\"mtk12\">colorValue</span><span class=\"mtk4\">}</span><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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The traditional way to accessing context values is by wrapping the child component in <code>Consumer</code>. From there, You can access values as props.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">ColorContext</span><span class=\"mtk1\">} </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./ColorContext&#39;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Page</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Component</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">render</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">ColorContext.Consumer</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">{</span><span class=\"mtk1\">(</span><span class=\"mtk12\">props</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=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span><span class=\"mtk4\">{</span><span class=\"mtk12\">props</span><span class=\"mtk4\">}</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=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">ColorContext.Consumer</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<h4 id=\"functional-component-and-hooks\" style=\"position:relative;\"><a href=\"#functional-component-and-hooks\" aria-label=\"functional component and hooks permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Functional component and Hooks</h4>\n<p> You can use <code>useContext</code>in functional components and its equivalent of <code>static contextType</code>. \t</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">React</span><span class=\"mtk1\">, { </span><span class=\"mtk12\">useContext</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;react&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">ColorContextfrom</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./ColorContext&#39;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">export</span><span class=\"mtk1\"> </span><span class=\"mtk12\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">HomePage</span><span class=\"mtk1\"> = () =&gt; {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">colorValue</span><span class=\"mtk1\">= </span><span class=\"mtk12\">useContext</span><span class=\"mtk1\">(</span><span class=\"mtk12\">ColorContext</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">return</span><span class=\"mtk1\"> &lt;</span><span class=\"mtk12\">div</span><span class=\"mtk1\">&gt;{</span><span class=\"mtk12\">ColorContext</span><span class=\"mtk1\">}&lt;/</span><span class=\"mtk12\">div</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<h3 id=\"updating-context\" style=\"position:relative;\"><a href=\"#updating-context\" aria-label=\"updating context permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Updating Context</h3>\n<p>We can update the context by updating the normal state. We just need to create a wrapper class that contains the state of context and the method to update it.\nExample code with file <code>ColorContext.js</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">React</span><span class=\"mtk1\">, { </span><span class=\"mtk12\">Component</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;react&#39;</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\">ColorContext</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">React</span><span class=\"mtk1\">.</span><span class=\"mtk11\">createContext</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">ColorContextProvider</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Component</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk3\">// Context state</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">state</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">color:</span><span class=\"mtk8\">&quot;&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=\"mtk3\">// Method to update state</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">setColor</span><span class=\"mtk1\"> = (</span><span class=\"mtk12\">color</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\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setState</span><span class=\"mtk1\">((</span><span class=\"mtk12\">prevState</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> ({ </span><span class=\"mtk12\">color</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=\"mtk11\">render</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\">children</span><span class=\"mtk1\"> } = </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">props</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">color</span><span class=\"mtk1\"> } = </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">state</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">ColorContext.Provider</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          this.</span><span class=\"mtk12\">setColor</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\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">{</span><span class=\"mtk12\">children</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">ColorContext.Provider</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">ColorContext</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">ColorContextProvider</span><span class=\"mtk1\"> }</span></span></code></pre>\n<p>Now you can update and view the user from the Context method.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">ColorContext</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./ColorContext&#39;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Page</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Component</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">static</span><span class=\"mtk1\"> </span><span class=\"mtk12\">contextType</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">ColorContext</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">render</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\">color</span><span class=\"mtk1\">, </span><span class=\"mtk12\">setColor</span><span class=\"mtk1\"> } = </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">context</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\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\">button</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">onClick</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</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\">newColorValue</span><span class=\"mtk1\">= </span><span class=\"mtk8\">&quot;black&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk11\">setColor</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">newColorValue</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\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          Update Color</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span><span class=\"mtk4\">{</span><span class=\"mtk8\">`Current Color Value: </span><span class=\"mtk4\">${</span><span class=\"mtk12\">color</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>In my opinion, It is much easier to use than Redux and requires very little code, so why wouldn't you use it?</p>\n<p>The problem with the context is simple: ** Everything that consumes the context re-renders each time the state of that reference changes. **</p>\n<p>This means that if you're consuming your context everywhere in your app, or worse, using one context for the state of your entire app, you'll end up re-rendering a ton everywhere.</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 .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk17 { color: #808080; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n</style>","frontmatter":{"date":"June 09, 2021","updated_date":null,"description":"Deep Dive into React's Context API with example","title":"React's Context API Guide with Example","tags":["React","Redux","Hooks"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/157af7ff069ab273224b4718433d9790/ee604/title-image.png","srcSet":"/static/157af7ff069ab273224b4718433d9790/69585/title-image.png 200w,\n/static/157af7ff069ab273224b4718433d9790/497c6/title-image.png 400w,\n/static/157af7ff069ab273224b4718433d9790/ee604/title-image.png 800w,\n/static/157af7ff069ab273224b4718433d9790/f3583/title-image.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Versha Gupta","github":"vershagupta","avatar":null}}}},{"node":{"excerpt":"In this tutorial, we will be covering some authentication concepts and learn about authentication and how to use JSON JWTweb tokens to…","fields":{"slug":"/engineering/implementing-authentication-on-vuejs-using-jwt/"},"html":"<p>In this tutorial, we will be covering some authentication concepts and learn about authentication and how to use JSON JWTweb tokens to authorize a Vue app. To continue in this tutorial, you should be comfortable using vue, vuex, and express.</p>\n<h2 id=\"overview\" style=\"position:relative;\"><a href=\"#overview\" aria-label=\"overview permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Overview</h2>\n<p>In our app, we have a login form. The user enters a username and password that is then posted to an endpoint. The flow of the app is the user opens the app, then the login page appears, the user submits the login form, which makes a post request to a login endpoint, then we check if the username and password check out, then we return a JWT and store the token in vuex and depending on the token we display a different page.</p>\n<p><img src=\"https://paper-attachments.dropbox.com/s_E8FB3BC64D80223D4CC4AFEEE119F2426D27A7EBE018696513C17DED12022079_1622019813698_AppWorkflow.png\" alt=\"App Workflow\"></p>\n<h2 id=\"setting-up-our-vue-app\" style=\"position:relative;\"><a href=\"#setting-up-our-vue-app\" aria-label=\"setting up our vue app permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Setting up our Vue app</h2>\n<p>You can start a new project using the <a href=\"https://cli.vuejs.org/guide/installation.html\">vue cli</a>, but you have to install the CLI first by running-</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm install -g @vue/cli</span>\n<span class=\"grvsc-line\"> OR</span>\n<span class=\"grvsc-line\">yarn global add @vue/cli</span></code></pre>\n<p>after the <code>cli</code> is installed, you can create a new project by running-</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">vue create jwt-auth-app</span></code></pre>\n<p>You will then be prompted to select some basic setup. In your setup, select Babel, Linter, Vue Router, and Vuex!. That’s all we need.</p>\n<h2 id=\"setup-express-server\" style=\"position:relative;\"><a href=\"#setup-express-server\" aria-label=\"setup express server permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Setup Express Server</h2>\n<p>To set up our server, we need to install <code>cors</code>, <code>dotenv</code>, <code>express</code>, and <code>nodemon</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm install cors dotenv express</span></code></pre>\n<p>Our server.js file is simplistic in a way that we just import express, tell it what port to listen to, and return “hello world” when we hit the base URL, and then we listen on that port.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;dotenv&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">config</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">express</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;express&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">cors</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;cors&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">app</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">express</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">port</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">3000</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk11\">cors</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk12\">express</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">get</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/&#39;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">send</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Hello World!&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">listen</span><span class=\"mtk1\">(</span><span class=\"mtk12\">port</span><span class=\"mtk1\">, () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">`Example app listening at http://localhost:</span><span class=\"mtk4\">${</span><span class=\"mtk12\">port</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span></code></pre>\n<h2 id=\"building-a-login-form\" style=\"position:relative;\"><a href=\"#building-a-login-form\" aria-label=\"building a login form permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Building a login form</h2>\n<p>In our views folder, we add <code>login.vue</code> and <code>welcome.vue</code> files, and in the <code>login.vue</code> file, we build out the login form. But before that, we want to add a route to our vue router so that we can navigate to the login and welcome page.\nSo for the <code>index.js</code> file of our router folder, we import the login and welcome view, and we add login and welcome routes for the components to point to.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Vue</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;vue&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">VueRouter</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;vue-router&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Login</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../views/Login.vue&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Welcome</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../views/Welcome.vue&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">Vue</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk12\">VueRouter</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">routes</span><span class=\"mtk1\"> = [</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">path:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;/&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Welcom&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">component:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Welcome</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">path:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Login&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">component:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Login</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">];</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">VueRouter</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">mode:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;history&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">base:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">process</span><span class=\"mtk1\">.</span><span class=\"mtk12\">env</span><span class=\"mtk1\">.</span><span class=\"mtk12\">BASE_URL</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">routes</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">router</span><span class=\"mtk1\">;</span></span></code></pre>\n<p>We can now navigate to both pages. On our welcome page, we want to check if the user is not logged in, then present the link they can click to navigate to the login page. We use a router link to achieve this.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">template</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Welcome</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">router-link</span><span class=\"mtk1\">  </span><span class=\"mtk12\">to</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Login</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk10\">router-link</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">template</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>In our login view, we scaffold our form. In the form, we are going to have two input boxes, one is the username input, and the other is a password. We then add a button with the type <code>submit</code> to submit the form. When we submit, we perform a login function in our script then set <code>preventDefault</code> on our form to stop the page from refreshing each time we click the login button.\nIn the script of our application, we model our input data by doing a two-way binding to the data state.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">template</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">LOGIN</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">form</span><span class=\"mtk1\"> </span><span class=\"mtk14\">@submit.prevent=&quot;login&quot;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk14\">&lt;input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">v-model</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;username&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;username&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">v-model</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">br</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;submit&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Login</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">form</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">&lt;/</span><span class=\"mtk12\">template</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">export default </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">data</span><span class=\"mtk1\">: () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">}</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p><img src=\"https://paper-attachments.dropbox.com/s_E8FB3BC64D80223D4CC4AFEEE119F2426D27A7EBE018696513C17DED12022079_1622020162212_loginForm.png\" alt=\"login form\"></p>\n<p>For the login method that runs when you click the button, we would like to perform an HTTP request to our express backend. We want to make a post request to our <code>/login</code> route we will create in our server.\nIn the fetch method, the first parameter is the URL you are sending a request to. Then the second is the object you are posting containing the headers, which contain information about the request, and the body containing the form data.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">export default </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">data</span><span class=\"mtk1\">: () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">methods</span><span class=\"mtk1\">: {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">login</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;http://localhost:3000/login&quot;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">method:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;POST&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk8\">&quot;Content-Type&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;application/json&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">body:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">password</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">}</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>In our server.js, we create a post request to the <code>/login</code> route and send back some <code>json</code> to test it out. Now, if we click login now, we get back a 200 ok message.</p>\n<p><em>Note: Make sure you set up</em> <code>*cors*</code> <em>so that you don't encounter an error message when hitting the</em> <code>*/login*</code> <em>route</em></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/login?&quot;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;hello ma guy&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span></code></pre>\n<h2 id=\"check-if-the-username-and-password-exist\" style=\"position:relative;\"><a href=\"#check-if-the-username-and-password-exist\" aria-label=\"check if the username and password exist permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Check if the username and password exist</h2>\n<p>The next step is to check if the username or password exists in a database or somewhere else. To not waste time dealing with a database, we can use a hardcoded username and password. In the post route, if somebody tries to log in with the exact login information we just hardcoded, we want to give the person a <em>green light</em> and log the person into the application; otherwise, we throw an error.</p>\n<p>Using the login payload we got from submitting the form, we can now check if the username and password are the same; else, we throw an error and respond with a status of 403 and a wrong login information message.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">USERNAME</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;uma victor&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">PASSWORD</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;8888&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">username</span><span class=\"mtk1\"> === </span><span class=\"mtk12\">USERNAME</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> === </span><span class=\"mtk12\">PASSWORD</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">1</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;uma victor&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;uma victor&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">403</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;wrong login information&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span></code></pre>\n<h2 id=\"jwt-authentication-in-our-app\" style=\"position:relative;\"><a href=\"#jwt-authentication-in-our-app\" aria-label=\"jwt authentication in our app permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>JWT Authentication in our app</h2>\n<p>This is the interesting part of the tutorial. Now, if you provide the correct login information and it checks out, the next step is to sign a JWT web token. Let’s first install the JWT plugin.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm install jsonwebtoken</span></code></pre>\n<p>also, make sure to import it at the top of your <code>server.js</code> file</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;jsonwebtoken&quot;</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>Then when the user login is successful, we want to send a JWT that is signed. So we import the JWTpackage. Then you sign in with a unique password. In a real application, we will want to have a <code>.env</code> file where we store the secret key. Then use <code>process.env</code> to grab and use it when signing our user model. Imagine we have a user object which we got back from our database with a unique ID, name, and username.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"12\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">post</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk1\">, (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">USERNAME</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;uma victor&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">PASSWORD</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;8888&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">username</span><span class=\"mtk1\">, </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">username</span><span class=\"mtk1\"> === </span><span class=\"mtk12\">USERNAME</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">password</span><span class=\"mtk1\"> === </span><span class=\"mtk12\">PASSWORD</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">1</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;uma victor&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;uma victor&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">token</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">jwt</span><span class=\"mtk1\">.</span><span class=\"mtk11\">sign</span><span class=\"mtk1\">(</span><span class=\"mtk12\">user</span><span class=\"mtk1\">, </span><span class=\"mtk12\">process</span><span class=\"mtk1\">.</span><span class=\"mtk12\">env</span><span class=\"mtk1\">.</span><span class=\"mtk12\">JWT_KEY</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">token</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">user</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">status</span><span class=\"mtk1\">(</span><span class=\"mtk7\">403</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;wrong login information&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span></code></pre>\n<p>It is the user object we want to sign, so when you send it to the client. We can uniquely identify them. The unique ID is also very important because when a server gets a request with a token, we want to know what uniquely identifies the request.\nNow when we enter the username and password in our form, we can see in the console that our JWT token is generated but is not encrypted. </p>\n<p>You can visit this site <a href=\"https://jwt.io/\">jwt.io</a> and paste in the token that was generated, and your token will be decoded and return information about your payload</p>\n<p><em>Note: The token is not encrypted, and anyone who gets access to the token can hit your server with it. Tokens normally have an expiry period of between 30 - 60 minutes</em></p>\n<h2 id=\"store-token-in-vuex\" style=\"position:relative;\"><a href=\"#store-token-in-vuex\" aria-label=\"store token in vuex permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Store Token in vuex</h2>\n<p>In our fetch method in the login view, we want to get back the token and the user and store it somewhere. Now we make our login method <code>async</code>, then we set our response to equal to the fetch method that returns the user and token, and we get back the user and token from the response.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"13\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">export default </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">data</span><span class=\"mtk1\">: () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">methods</span><span class=\"mtk1\">: {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">login</span><span class=\"mtk1\">(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">e</span><span class=\"mtk1\">.</span><span class=\"mtk11\">preventDefault</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">response</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;http://localhost:3000/login&quot;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">method:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;POST&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk8\">&quot;Content-Type&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;application/json&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">body:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">password</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">}</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>In our store, we add the user and token data in our state and set them to <code>null</code> initially. You can use the token to see if the user is logged in or not. If the token is <code>null</code>, then we are not logged in, but if it’s set to something, then we are probably logged in.\nWe create a <code>setUser</code> mutation in our mutation object that sets the state to the user object. We also create a <code>setToken</code> mutation to assign our token.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"14\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Vue</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;vue&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Vuex</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;vuex&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">Vue</span><span class=\"mtk1\">.</span><span class=\"mtk11\">use</span><span class=\"mtk1\">(</span><span class=\"mtk12\">Vuex</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Vuex</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Store</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">state:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">user:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">null</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">token:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">null</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">mutations:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">setUser</span><span class=\"mtk1\">(</span><span class=\"mtk12\">state</span><span class=\"mtk1\">, </span><span class=\"mtk12\">user</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">state</span><span class=\"mtk1\">.</span><span class=\"mtk12\">user</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">user</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">setToken</span><span class=\"mtk1\">(</span><span class=\"mtk12\">state</span><span class=\"mtk1\">, </span><span class=\"mtk12\">token</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">state</span><span class=\"mtk1\">.</span><span class=\"mtk12\">token</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">token</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">actions:</span><span class=\"mtk1\"> {},</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">getters:</span><span class=\"mtk1\"> {},</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span></code></pre>\n<p><em>Note: It is best practice to always call mutations from our actions, but since our mutations can easily be traced, we are calling the mutations directly</em></p>\n<p>In the login view, we can import <code>mapMutations</code> from vuex and map the <code>setUser</code> and <code>setToken</code> mutation. We can now call the mutations from the login method.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"15\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">import </span><span class=\"mtk4\">{</span><span class=\"mtk1\"> </span><span class=\"mtk12\">mapMutations</span><span class=\"mtk1\"> </span><span class=\"mtk4\">}</span><span class=\"mtk1\"> from &quot;vuex&quot;;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">export default </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">data</span><span class=\"mtk1\">: () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">methods</span><span class=\"mtk1\">: {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ...</span><span class=\"mtk11\">mapMutations</span><span class=\"mtk1\">([</span><span class=\"mtk8\">&quot;setUser&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;setToken&quot;</span><span class=\"mtk1\">]),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk11\">login</span><span class=\"mtk1\">(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">e</span><span class=\"mtk1\">.</span><span class=\"mtk11\">preventDefault</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">response</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;http://localhost:3000/login&quot;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">method:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;POST&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk8\">&quot;Content-Type&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;application/json&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">body:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">username:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">username</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">password</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">user</span><span class=\"mtk1\">, </span><span class=\"mtk12\">token</span><span class=\"mtk1\"> } = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setUser</span><span class=\"mtk1\">(</span><span class=\"mtk12\">user</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setToken</span><span class=\"mtk1\">(</span><span class=\"mtk12\">token</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">}</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>Now that we're logged in, our state has been mutated and updated with the information from our form. But after we login, we want to redirect to our welcome page using the <code>$router.push(\"/\")</code> method to redirect to the home page, which is also our welcome page. </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"16\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">$router</span><span class=\"mtk1\">.</span><span class=\"mtk11\">push</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/&quot;</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>// image of the welcome page here\nSince you are logged in, you don’t want the login button showing anymore on the welcome page. You can use a getter from our store to do this. We check if the token is null or not and return <code>true</code> or <code>false</code>. </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"17\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">getters: {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">isLoggedIn</span><span class=\"mtk1\">(</span><span class=\"mtk12\">state</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> !!</span><span class=\"mtk12\">state</span><span class=\"mtk1\">.</span><span class=\"mtk12\">token</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">},</span></span></code></pre>\n<p>then in our welcome component template, we can use now map to our Getter and use the <code>v-if</code> directive to display the login button if <code>isLoggedIn</code> is <code>true</code> or <code>false</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"18\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">template</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    Welcome</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">router-link</span><span class=\"mtk1\"> </span><span class=\"mtk12\">v-if</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;!isLoggedIn&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">to</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Login</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk10\">router-link</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">template</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">import </span><span class=\"mtk4\">{</span><span class=\"mtk1\"> </span><span class=\"mtk12\">mapGetters</span><span class=\"mtk1\"> </span><span class=\"mtk4\">}</span><span class=\"mtk1\"> from &quot;vuex&quot;;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">export default </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">computed</span><span class=\"mtk1\">: {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ...</span><span class=\"mtk11\">mapGetters</span><span class=\"mtk1\">([</span><span class=\"mtk8\">&quot;isLoggedIn&quot;</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">}</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>In this tutorial, we looked at how to authenticate a person using the JSON web token. We created a login form and used an express server for the login route in the application using Vue.js as a frontend framework.</p>\n<h2 id=\"resources\" style=\"position:relative;\"><a href=\"#resources\" aria-label=\"resources permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Resources</h2>\n<ul>\n<li><a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/Vuejs/AuthenticationUsingJWT\">GIthub souce code</a></li>\n<li><a href=\"https://jwt.io/\">jwt.io</a></li>\n<li><a href=\"https://www.loginradius.com/blog/engineering/jwt/\">What are json web token</a></li>\n</ul>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk17 { color: #808080; }\n  .dark-default-dark .mtk14 { color: #F44747; }\n</style>","frontmatter":{"date":"June 02, 2021","updated_date":null,"description":"In recent times, when building a modern application, users are required to verify their identity. The process by which we carry out this verification is what we call authentication, and in this tutorial, we would look at how we can carry out this task using JWTauthentication on a Vuejs app.","title":"Implementing Authentication on Vue.js using JWTtoken","tags":["Auth","JWT","Vue.js"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.8867924528301887,"src":"/static/ececadbcd1e6705ff5e9039485918dad/ee604/coverimage.png","srcSet":"/static/ececadbcd1e6705ff5e9039485918dad/69585/coverimage.png 200w,\n/static/ececadbcd1e6705ff5e9039485918dad/497c6/coverimage.png 400w,\n/static/ececadbcd1e6705ff5e9039485918dad/ee604/coverimage.png 800w,\n/static/ececadbcd1e6705ff5e9039485918dad/f3583/coverimage.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Uma Victor","github":"uma-victor1","avatar":null}}}},{"node":{"excerpt":"Introduction Dictionaries Dictionary<TKey, TValue> is used for storing a key-value pair. It is a generic collection that is defined in the…","fields":{"slug":"/engineering/how-to-create-and-use-dictionary-csharp/"},"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>Dictionaries <code>Dictionary&#x3C;TKey, TValue></code> is used for storing a key-value pair. It is a generic collection that is defined in the <em>System.Collection.Generic</em> namespace and implements the <code>IDictionary&#x3C;TKey, TValue></code> interface.</p>\n<h2 id=\"create-a-dictionary\" style=\"position:relative;\"><a href=\"#create-a-dictionary\" aria-label=\"create a dictionary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create a dictionary</h2>\n<p>Suppose we want to store the scores of a player in a cricket match, Then we have to save the key as the name of the player and score as value.</p>\n<p>To create a dictionary of key and value type as a string and int, respectively, we just simply need to initialize as below.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">Dictionary</span><span class=\"mtk1\">&lt;</span><span class=\"mtk4\">string</span><span class=\"mtk1\">, </span><span class=\"mtk4\">int</span><span class=\"mtk1\">&gt; </span><span class=\"mtk12\">dict</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Dictionary</span><span class=\"mtk1\">&lt;</span><span class=\"mtk4\">string</span><span class=\"mtk1\">, </span><span class=\"mtk4\">int</span><span class=\"mtk1\">&gt;();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">Dictionary</span><span class=\"mtk1\">&lt;</span><span class=\"mtk4\">string</span><span class=\"mtk1\">, </span><span class=\"mtk4\">int</span><span class=\"mtk1\">&gt; </span><span class=\"mtk12\">dict1</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Dictionary</span><span class=\"mtk1\">&lt;</span><span class=\"mtk4\">string</span><span class=\"mtk1\">, </span><span class=\"mtk4\">int</span><span class=\"mtk1\">&gt;(</span><span class=\"mtk7\">5</span><span class=\"mtk1\">); </span><span class=\"mtk3\">// Creates a dictionary with default initial capacity of 5</span></span></code></pre>\n<p>The first line will create a dictionary with string type of key and int type of value and will have the initial default capacity as well default equality comparer for the key type.</p>\n<p>The Second line will create the same dictionary as line 1 except for the initial default capacity. It will create a dictionary with an initial default capacity of 5.</p>\n<p>We can create the dictionary by using the different constructors of the dictionary. Here I have talked about the two constructors only.</p>\n<h2 id=\"add-elements\" style=\"position:relative;\"><a href=\"#add-elements\" aria-label=\"add elements permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Add elements</h2>\n<p>We can add the elements in the dictionary by using add method of it.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">dict</span><span class=\"mtk1\">.</span><span class=\"mtk11\">Add</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Player&quot;</span><span class=\"mtk1\">,</span><span class=\"mtk7\">42</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">dict</span><span class=\"mtk1\">.</span><span class=\"mtk11\">Add</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Player1&quot;</span><span class=\"mtk1\">,</span><span class=\"mtk7\">38</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>It will add the elements in the dictionary. </p>\n<p><strong>Note:</strong> <em>Keys</em> can not be <code>null</code> or <code>duplicate</code>. If we add the duplicate or null as a key, then the application will throw the run time exception, but <em>Values</em> can be <code>null</code> or <code>duplicate</code>.</p>\n<h2 id=\"traverse\" style=\"position:relative;\"><a href=\"#traverse\" aria-label=\"traverse permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Traverse</h2>\n<p>To traverse through a dictionary, we can use a foreach loop or a for a loop.</p>\n<h3 id=\"foreach-loop\" style=\"position:relative;\"><a href=\"#foreach-loop\" aria-label=\"foreach loop permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>foreach loop</h3>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">foreach</span><span class=\"mtk1\"> (</span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">item</span><span class=\"mtk1\"> </span><span class=\"mtk15\">in</span><span class=\"mtk1\"> </span><span class=\"mtk12\">dict</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\">Console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">WriteLine</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Key &quot;</span><span class=\"mtk1\">+ </span><span class=\"mtk12\">item</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Key</span><span class=\"mtk1\"> +</span><span class=\"mtk8\">&quot; Value &quot;</span><span class=\"mtk1\">+ </span><span class=\"mtk12\">item</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Value</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<h3 id=\"for-loop\" style=\"position:relative;\"><a href=\"#for-loop\" aria-label=\"for loop permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>for loop</h3>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">for</span><span class=\"mtk1\"> (</span><span class=\"mtk4\">int</span><span class=\"mtk1\"> </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">0</span><span class=\"mtk1\">; </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> &lt; </span><span class=\"mtk12\">dict</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Count</span><span class=\"mtk1\">; </span><span class=\"mtk12\">i</span><span class=\"mtk1\">++)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk12\">Console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">WriteLine</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Key &quot;</span><span class=\"mtk1\"> + </span><span class=\"mtk12\">dict</span><span class=\"mtk1\">.</span><span class=\"mtk11\">ElementAt</span><span class=\"mtk1\">(</span><span class=\"mtk12\">i</span><span class=\"mtk1\">).</span><span class=\"mtk12\">Key</span><span class=\"mtk1\"> + </span><span class=\"mtk8\">&quot; Value &quot;</span><span class=\"mtk1\"> + </span><span class=\"mtk12\">dict</span><span class=\"mtk1\">.</span><span class=\"mtk11\">ElementAt</span><span class=\"mtk1\">(</span><span class=\"mtk12\">i</span><span class=\"mtk1\">).</span><span class=\"mtk12\">Value</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>In the above code, we are using the </p>\n<ol>\n<li><strong>Key</strong> Property of dictionary element which will return the Key of the dictionary element.</li>\n<li><strong>Value</strong> Property of dictionary element, which will return the value of the dictionary element.</li>\n<li><strong>Count</strong> Property which will return the number of elements in the dictionary.</li>\n<li><strong>ElementAt(int index)</strong> method of a dictionary, which will return the element at the specified index.</li>\n</ol>\n<h2 id=\"getupdate-specified-keys-value\" style=\"position:relative;\"><a href=\"#getupdate-specified-keys-value\" aria-label=\"getupdate specified keys value permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Get/Update specified key's value</h2>\n<p>To get the specified key's value from the dictionary, we can directly use the key as an index. </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">Console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">WriteLine</span><span class=\"mtk1\">(</span><span class=\"mtk12\">dict</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&quot;Player&quot;</span><span class=\"mtk1\">]); </span><span class=\"mtk3\">// Prints 42</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">Console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">WriteLine</span><span class=\"mtk1\">(</span><span class=\"mtk12\">dict</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&quot;Player1&quot;</span><span class=\"mtk1\">]); </span><span class=\"mtk3\">// Prints 38</span></span></code></pre>\n<p>To update the specified key's value of the dictionary, we can set it as below.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">dict</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&quot;Player&quot;</span><span class=\"mtk1\">]=</span><span class=\"mtk7\">45</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">Console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">WriteLine</span><span class=\"mtk1\">(</span><span class=\"mtk12\">dict</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&quot;Player1&quot;</span><span class=\"mtk1\">]); </span><span class=\"mtk3\">// Prints 45</span></span></code></pre>\n<p><strong>Note:</strong> </p>\n<ol>\n<li>It will give the run time exception if the given key is not present in the dictionary, and we try to access the value of that key so we can first check for the key using the <strong>ContainsKey(TKey)</strong> method of the dictionary which will return true/false if the key is present or not in the dictionary.</li>\n<li>Suppose if we want to set the value of a key that is not present in the dictionary, then it will automatically add that element into the dictionary and sets the value of it.</li>\n</ol>\n<h2 id=\"remove\" style=\"position:relative;\"><a href=\"#remove\" aria-label=\"remove permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Remove</h2>\n<p>To remove elements from a dictionary, we can use the below methods.</p>\n<h3 id=\"remove-specific-key\" style=\"position:relative;\"><a href=\"#remove-specific-key\" aria-label=\"remove specific key permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Remove specific key</h3>\n<p>To remove a specific key, we can use the <strong>Remove(TKey)</strong> method of the dictionary.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">dict</span><span class=\"mtk1\">.</span><span class=\"mtk11\">Remove</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Player1&quot;</span><span class=\"mtk1\">); </span><span class=\"mtk3\">// Removes Player1 from dictionary</span></span></code></pre>\n<h3 id=\"clear-dictionary\" style=\"position:relative;\"><a href=\"#clear-dictionary\" aria-label=\"clear dictionary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Clear dictionary</h3>\n<p>To clear all the elements of the dictionary, we can use the <strong>Clear()</strong> method of the dictionary.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">dict</span><span class=\"mtk1\">.</span><span class=\"mtk11\">Clear</span><span class=\"mtk1\">(); </span><span class=\"mtk3\">// Clears all the elements and count will be 0</span></span></code></pre>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>In this article, We have learned about some of the basics of dictionaries. Dictionaries help to use to manage data in Key-Value pair, which we can easily access and manipulate the data accordingly.</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 .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n</style>","frontmatter":{"date":"May 27, 2021","updated_date":null,"description":"In this article, we will talk about how to create and use the Dictionary in C#.","title":"How to create and use the Dictionary in C#","tags":["C#","Dictionary"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/70d1172c5171ae195aeb525bdf6086b3/ee604/coverimage.png","srcSet":"/static/70d1172c5171ae195aeb525bdf6086b3/69585/coverimage.png 200w,\n/static/70d1172c5171ae195aeb525bdf6086b3/497c6/coverimage.png 400w,\n/static/70d1172c5171ae195aeb525bdf6086b3/ee604/coverimage.png 800w,\n/static/70d1172c5171ae195aeb525bdf6086b3/f3583/coverimage.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Hemant Manwani","github":"hemant404","avatar":null}}}},{"node":{"excerpt":"While most of you — developers and architects — understand the need for strong password security and practice it, your users might not.  For…","fields":{"slug":"/engineering/risk-based-authentication/"},"html":"<p>While most of you — developers and architects — understand the need for strong password security and practice it, your users might not. </p>\n<p>For years security researchers have been hollering about the risks of weak, repeated passwords. Still, average Joe seems to be complacent about it and reuses the same or similar passwords across multiple logins, despite the fact that even a strong password is secure only if used for a single login.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 397px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 74.3073047858942%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAABAACBf/EABUBAQEAAAAAAAAAAAAAAAAAAAEC/9oADAMBAAIQAxAAAAHmqXiaPOg//8QAGRABAAIDAAAAAAAAAAAAAAAAAQACEiEx/9oACAEBAAEFAhsx0w6jkXZ//8QAFhEBAQEAAAAAAAAAAAAAAAAAABEh/9oACAEDAQE/AcV//8QAFREBAQAAAAAAAAAAAAAAAAAAECH/2gAIAQIBAT8Bp//EABkQAAIDAQAAAAAAAAAAAAAAAAABECExof/aAAgBAQAGPwLeFRg2qLP/xAAbEAACAwEBAQAAAAAAAAAAAAAAAREhMVFBYf/aAAgBAQABPyFxlT8FJV6NT0RrCF5GnVSiNU//2gAMAwEAAgADAAAAEED/AP/EABgRAAIDAAAAAAAAAAAAAAAAAAABITFx/9oACAEDAQE/EFCjB//EABYRAAMAAAAAAAAAAAAAAAAAAAABEf/aAAgBAgEBPxCsyH//xAAeEAEAAwEAAQUAAAAAAAAAAAABESExAFFhgZGhwf/aAAgBAQABPxBIXO4fXEpRMIzvodKlfgH51yGyjkuJOQUeC83goJRpgJPbv//Z'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"https://twitter.com/JohnLegere/status/371699808014462976/photo/1\"\n        title=\"https://twitter.com/JohnLegere/status/371699808014462976/photo/1\"\n        src=\"/static/681818a64c296cde25974e60e694c247/9157c/incorrect.jpg\"\n        srcset=\"/static/681818a64c296cde25974e60e694c247/9157c/incorrect.jpg 397w\"\n        sizes=\"(max-width: 397px) 100vw, 397px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>A good password manager can alleviate the problem of remembering tens of passwords, if not hundreds. However, in reality, the average Joe doesn't invest in a password manager and carries on with life. </p>\n<p>So, what's the greater risk? You may ask.</p>\n<p>Millions of data records, including login credentials, are being exposed in data breaches, which continue to make headlines around the world. In fact, data breaches globally <a href=\"https://www.securitymagazine.com/articles/94076-the-top-10-data-breaches-of-2020\">exposed more than 36 billion records in 2020</a>.</p>\n<p>Cybercriminals get access to these exposed records in black markets (generally on the dark web) and use them to perform credential stuffing and account takeover attacks or commit fraud. </p>\n<p>Whether it's yours or your users' fault, such type of attacks damage brand reputation, make your business liable to legal damages, and impact user experience. </p>\n<p>You should take the onus upon yourself to ensure user access to your apps or portals is as secure as possible without impacting user experience. This is where risk-based authentication (RBA) — also known as adaptive authentication — comes into play.  </p>\n<h2 id=\"what-is-risk-based-authentication-rba\" style=\"position:relative;\"><a href=\"#what-is-risk-based-authentication-rba\" aria-label=\"what is risk based authentication rba permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is Risk-based Authentication (RBA)?</h2>\n<p>RBA is a process of assessing the risk of an authentication request in real-time and requesting additional layers of authentication and identification based on the risk profile to validate that a user attempting to authenticate is who they claim to be. </p>\n<p>The risk is usually assessed based on various parameters and the environment from which the user is attempting to authenticate. Some common parameters used for risk profiling include:</p>\n<ul>\n<li>User's geolocation</li>\n<li>Origin IP address </li>\n<li>Sensitivity of the information or system the user wants to access</li>\n<li>User's device. Is it a familiar device or a new device?</li>\n</ul>\n<p>Based on the risk assessed, an RBA system requests additional methods of authentication, such as:</p>\n<ul>\n<li>A verification link sent to the user's registered email ID</li>\n<li>An OTP sent to the user's phone or email ID </li>\n<li>OTP generated from user's authenticator app</li>\n<li>User's preset security questions</li>\n</ul>\n<p>RBA is different from multi-factor authentication (MFA). MFA is a static authentication method — that is, regardless of the risk of an authentication request, this method requires an additional layer(s) of validation. </p>\n<p>On the other hand, RBA is a non-static authentication method that requires additional authentication factors only when necessary based on the risk profile — as a result, RBA provides a better user experience. </p>\n<p>Now, it's clear that better safe than sorry when it comes to authenticating users, and implementing RBA reduce account compromise risk on your apps. </p>\n<p>That said, RBA doesn't have to stop at user authentication; you can extend it to signups, payments, and other types of online transactions.</p>\n<h2 id=\"how-to-implement-risk-based-authentication-rba\" style=\"position:relative;\"><a href=\"#how-to-implement-risk-based-authentication-rba\" aria-label=\"how to implement risk based authentication rba permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to Implement Risk-based Authentication (RBA)?</h2>\n<p>You have two options:</p>\n<ul>\n<li>Develop an RBA system in-house</li>\n<li>Rely on an RBA provider </li>\n</ul>\n<p>Yes, developing an RBA system in-house is possible. But, you should ponder upon some important details: </p>\n<ul>\n<li>At what cost? </li>\n<li>Does our team have the time and capability to develop and maintain an in-house RBA system that is reliable?</li>\n<li>Can we keep it up-to-date with threat intelligence to get ahead of evolving attacks and data breaches happening elsewhere that might affect our users?</li>\n</ul>\n<p>If you got convincing responses to the above questions, you may go ahead and develop your in-house RBA system. </p>\n<p>But a lot of you might not have that sort of resources or just don't want to focus on non-core development projects. In this case, you can rely on a reputed RBA provider -- for example, LoginRadius.😉</p>\n<p>When choosing an RBA provider, make sure the solution meets the following criteria:</p>\n<ul>\n<li>How easy is it to implement and maintain?</li>\n<li>Does it offer out-of-the-box rules and risk profiling methods for quick configuration?</li>\n<li>Can you customize the solution's AI/ML or statistical models based on your in-house expertise?</li>\n<li>How well does it integrate with your existing authentication strategy?</li>\n<li>Does it offer comprehensive CIAM features beyond RBA so that you can reliably depend on a single vendor and provide a unified user experience?</li>\n<li>How effectively it stops fraud or accounts takeover in real-time?</li>\n</ul>\n<p>Once you have evaluated and finalized the vendor, it is vital to test the RBA solution and ensure that the user experience is as expected while minimizing risk.</p>\n<p>Want to learn more about RBA and test how RBA works in LoginRadius? <a href=\"https://accounts.loginradius.com/auth.aspx?action=register&#x26;return_url=https://dashboard.loginradius.com/login\">Signup</a> for a free account here.</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":"May 25, 2021","updated_date":null,"description":"RBA is a process of assessing the risk of an authentication request in real-time and requesting additional layers of authentication and identification based on the risk profile to validate that a user attempting to authenticate is who they claim to be.","title":"What is Risk-Based Authentication? And Why Should You Implement It?","tags":["RBA","Authentication"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/ef5a017980017a63c415e5259ef6d0a2/14b42/cover.jpg","srcSet":"/static/ef5a017980017a63c415e5259ef6d0a2/f836f/cover.jpg 200w,\n/static/ef5a017980017a63c415e5259ef6d0a2/2244e/cover.jpg 400w,\n/static/ef5a017980017a63c415e5259ef6d0a2/14b42/cover.jpg 800w,\n/static/ef5a017980017a63c415e5259ef6d0a2/47498/cover.jpg 1200w,\n/static/ef5a017980017a63c415e5259ef6d0a2/0e329/cover.jpg 1600w,\n/static/ef5a017980017a63c415e5259ef6d0a2/be7fd/cover.jpg 3999w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Raghunath Reddy","github":"raghunath-r-a","avatar":null}}}}]},"markdownRemark":{"excerpt":"Google has prepared a roadmap to restrict third-party cookies in Chrome. Since 04 January 2024, Chrome has rolled out third-party cookie…","fields":{"slug":"/engineering/identity-impact-of-google-chrome-thirdparty-cookie-restrictions/"},"html":"<p>Google has prepared a roadmap to restrict third-party cookies in Chrome. Since 04 January 2024, Chrome has rolled out third-party cookie restrictions for 1% of stable clients and 20% of Canary, Dev, and Beta clients.</p>\n<p><strong>What does it mean for user authentication?</strong></p>\n<p>On one hand, Google believes third-party cookies are widely used for cross-site tracking, greatly affecting user privacy. Hence, Google wants to phase out (or restrict) supporting third-party cookies in Chrome by early Q2 2025 (subject to regulatory processes).</p>\n<p>On the other hand, Google introduced Privacy Sandbox to support the use cases (other than cross-site tracking and advertising) previously implemented using third-party cookies.</p>\n<p>In this article, we’ll discuss:</p>\n<ul>\n<li>How is user authentication (identity) affected?</li>\n<li>What is Google offering as part of Privacy Sandbox to support various identity use cases when third-party cookies are phased out?</li>\n</ul>\n<h2 id=\"how-is-user-authentication-affected\" style=\"position:relative;\"><a href=\"#how-is-user-authentication-affected\" aria-label=\"how is user authentication affected permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 is User Authentication Affected?</h2>\n<p>Third-party cookie restrictions affect user authentication in three ways, as follows.</p>\n<h3 id=\"external-identity-providers\" style=\"position:relative;\"><a href=\"#external-identity-providers\" aria-label=\"external identity providers permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>External Identity Providers</h3>\n<p>If your website or app uses an external Identity Provider (IdP) — like LoginRadius, the IdP sets a third-party cookie when the user authenticates on your app.</p>\n<h3 id=\"web-sso\" style=\"position:relative;\"><a href=\"#web-sso\" aria-label=\"web sso permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Web SSO</h3>\n<p>If you have multiple apps across domains within your organization and authentication is handled using an IdP (internal or external) with web SSO, you already use third-party cookies to facilitate seamless access for each user using a single set of credentials.</p>\n<p>If you have implemented web SSO with one primary domain and multiple sub-domains of the primary domain, third-party cookie restrictions may not apply. For now, Google doesn’t consider the cookies set by sub-domains as third-party cookies, although this stance may change in the future.</p>\n<p>For example, you have apps at <code>example.com</code>, <code>travel.example.com</code>, <code>stay.example.com</code>, and web SSO is handled by <code>auth.example.com</code>. In this case, third-party cookie restrictions don’t apply.</p>\n<h3 id=\"federated-sso\" style=\"position:relative;\"><a href=\"#federated-sso\" aria-label=\"federated sso permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Federated SSO</h3>\n<p>Federated SSO is similar to, albeit different from, web SSO. It can handle multiple IdPs and applications—aka., Service Providers (SPs)—spanning multiple organizations. It can also implement authentication scenarios that are usually implemented through web SSO.</p>\n<p>Usually, authentication is handled on a separate pop-up or page when the user wants to authenticate rather than on the application or website a user visits. </p>\n<p>For example, you already use federated SSO if you facilitate authentication for a set of apps through multiple social identity providers as well as traditional usernames and passwords.</p>\n<blockquote>\n<p><strong>Note</strong>: It is also possible to store tokens locally, not within cookies. In this case, third-party cookie restrictions won’t affect token-based authentication. However, the restrictions still affect authentication where tokens are stored within third-party cookies (a common and secure method).</p>\n</blockquote>\n<h2 id=\"chromes-alternatives-for-third-party-cookies\" style=\"position:relative;\"><a href=\"#chromes-alternatives-for-third-party-cookies\" aria-label=\"chromes alternatives for third party cookies permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Chrome’s Alternatives for Third-Party Cookies</h2>\n<p>Google has been developing alternative features and capabilities for Chrome to replace third-party cookies as part of its Privacy Sandbox for Web initiative.</p>\n<p>Specific to authentication, Google recommends the following:</p>\n<ol>\n<li>Cookies Having Independent Partitioned State (CHIPS)</li>\n<li>Storage Access API</li>\n<li>Related Website Sets</li>\n<li>Federated Credential Management (FedCM) API</li>\n</ol>\n<h3 id=\"cookies-having-independent-partitioned-state-chips\" style=\"position:relative;\"><a href=\"#cookies-having-independent-partitioned-state-chips\" aria-label=\"cookies having independent partitioned state chips permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Cookies Having Independent Partitioned State (CHIPS)</h3>\n<p><a href=\"https://developers.google.com/privacy-sandbox/3pcd/chips\">CHIPS</a> are a restricted way of setting third-party cookies on a top-level site without making them accessible on other top-level sites. Thus, they limit cross-site tracking and enable specific cross-site functionalities, such as maps, chat, and payment embeds.</p>\n<p>For example, a user visits <code>a.com</code> with a map embed from <code>map-example.com</code>, which can set a partitioned cookie that is only accessible on a.com. </p>\n<p>If the user visits <code>b.com</code> with a map embed from <code>map-example.com</code>, it cannot access the partitioned cookie set on <code>a.com</code>. It has to create a separate partitioned cookie specific to <code>b.com</code>, thus blocking cross-site tracking yet allowing limited cross-site functionality.</p>\n<p>You should specifically opt for partitioned cookies (CHIPS), which are set with partitioned and secure cookie attributes.</p>\n<p>If you’re using an external identity provider for your application, CHIPS is a good option to supplant third-party cookie restrictions. </p>\n<p>However, CHIPS may not be ideal if you have a web SSO or federated SSO implementation. It creates separate partitioned cookies for each application with a separate domain, which can increase complexity and create compatibility issues.</p>\n<h3 id=\"storage-access-api\" style=\"position:relative;\"><a href=\"#storage-access-api\" aria-label=\"storage access 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>Storage Access API</h3>\n<p>With <a href=\"https://developers.google.com/privacy-sandbox/3pcd/storage-access-api\">Storage Access API</a>, you can access the local storage in a third-party context through iframes, similar to when users visit it as a top-level site in a first-party context. That is, it gives access to unpartitioned cookies and storage.</p>\n<p>Storage Access API requires explicit user approval to grant access, similar to locations, camera, and microphone permissions. If the user denies access, unpartitioned cookies and storage won’t be accessible in a third-party context.</p>\n<p>It is most suitable when loading cross-site resources and interactions, such as:</p>\n<p>Verifying user sessions when allowing interactions on an embedded social post or providing personalization for an embedded video.\nEmbedded documents requiring user verification status to be accessible.</p>\n<p>As it requires explicit user approval, it is advisable to use Storage Access API when you can’t implement an identity use case with the other options.</p>\n<h3 id=\"related-website-sets\" style=\"position:relative;\"><a href=\"#related-website-sets\" aria-label=\"related website sets permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Related Website Sets</h3>\n<p>With <a href=\"https://developers.google.com/privacy-sandbox/3pcd/related-website-sets\">Related Website Sets</a>, you can declare a <code>primary</code> website and <code>associatedSites</code> for limited purposes to grant third-party cookie access and local storage for a limited number of sites.</p>\n<p>Chrome automatically recognizes related website sets declared, accepted, and maintained in this open-source GitHub repository: <a href=\"https://github.com/GoogleChrome/related-website-sets\">Related Website Sets</a></p>\n<p>It provides access through Storage Access API directly without prompting for user approval, but only after the user interacts with the relevant iframe.</p>\n<p>It is important to declare a limited number of domains in related website sets that are meaningful and used for specific purposes. Google may block or suspend any exploitative use of this feature.</p>\n<p>The top-level site can also request approval for specific cross-site resources and scripts to Storage Access API using <code>resuestStorageAccessFor()</code> API.</p>\n<p>If you’re using an external identity provider for your web application, you can declare the domain of the identity provider in the related set to ensure limited third-party cookies and storage access to the identity provider, thus ensuring seamless user authentication.</p>\n<p>Related Website Sets can also work to supplement third-party cookie restrictions in web SSO and federated SSO if the number of web applications (or domains) is limited.</p>\n<h3 id=\"federated-credential-management-fedcm-api\" style=\"position:relative;\"><a href=\"#federated-credential-management-fedcm-api\" aria-label=\"federated credential management fedcm 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>Federated Credential Management (FedCM) API</h3>\n<p>FedCM API enables federated SSO without third-party cookies.</p>\n<p>With FedCM API, a user follows these steps for authentication:</p>\n<ol>\n<li>The User navigates to a Service Provider (SP) — aka., Relying Party (RP)</li>\n<li>As the user requests to authenticate, the SP requests the browser through FedCM API to initiate authentication.</li>\n<li>The browser displays a list of available identity providers (supported by the RP), such as social IdPs like Google, Apple, LinkedIn, and Facebook, or other OAuth IdPs like LoginRadius.</li>\n<li>Once the user selects an IdP, the browser communicates with the IdP. Upon valid authentication, the IdP generates a secure token.\nThe browser delivers this secure token to the RP to facilitate user authorization.</li>\n</ol>\n<p>You can access a user demo of FedCM here: <a href=\"https://fedcm-rp-demo.glitch.me/\">FedCM</a>. </p>\n<p>For more information about implementing federated SSO with FedCM API, go through the <a href=\"https://developers.google.com/privacy-sandbox/3pcd/fedcm-developer-guide\">FedCM developer guide</a>.</p>\n<h2 id=\"how-is-loginradius-preparing-for-the-third-party-cookie-phase-out\" style=\"position:relative;\"><a href=\"#how-is-loginradius-preparing-for-the-third-party-cookie-phase-out\" aria-label=\"how is loginradius preparing for the third party cookie phase out permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 is LoginRadius Preparing for the Third-party Cookie Phase-out?</h2>\n<p>Firstly, we’re committed to solving our customers' user identity pain points — and preparing for the third-party cookies phase-out is no different.</p>\n<p>We’ll implement the most relevant and widely useful solutions to facilitate a smooth transition for our customers.</p>\n<p>Please subscribe to our blog for more information. We’ll update you on how we help with the third-party cookie phase-out.</p>\n<h2 id=\"in-conclusion\" style=\"position:relative;\"><a href=\"#in-conclusion\" aria-label=\"in 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>In Conclusion</h2>\n<p>The proposed changes to phase out third-party cookies and suggested alternatives are evolving as Google has been actively collaborating and discussing changes with the border community.</p>\n<p>Moreover, browsers like Firefox, Safari, and Edge may approach restricting third-party cookies differently than Google does.</p>\n<p>From LoginRadius, we’ll keep you updated on what we’re doing as a leading Customer Identity and Access Management (CIAM) vendor to prepare for the third-party cookie phase-out.</p>\n<h2 id=\"glossary\" style=\"position:relative;\"><a href=\"#glossary\" aria-label=\"glossary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Glossary</h2>\n<p><strong>Top-level site</strong>: It is the primary site a user has visited.</p>\n<p><strong>First-party cookie</strong>: A cookie set by the top-level site.</p>\n<p><strong>Third-party cookie</strong>: A cookie set by a domain other than the top-level site. For example, let’s assume that a user has visited <code>a.com</code>, which might use an embed from <code>loginradius.com</code> to facilitate authentication. If <code>loginradius.com</code> sets a cookie when the user visits <code>a.com</code>, it is called a third-party cookie as the user hasn’t directly visited <code>loginradius.com</code>.</p>\n<h2 id=\"references\" style=\"position:relative;\"><a href=\"#references\" aria-label=\"references permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>References</h2>\n<ul>\n<li><a href=\"https://developers.google.com/privacy-sandbox/3pcd/prepare/prepare-for-phaseout\">Changes to Chrome's treatment of third-party cookies</a></li>\n<li><a href=\"https://developers.google.com/privacy-sandbox/3pcd/guides/identity\">Check the impact of the third-party cookie changes on your sign-in workflows</a></li>\n</ul>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"July 08, 2024","updated_date":null,"description":"Google Chrome has planned to phase out third-party cookies, which will affect different website functionalities depending on third-party cookies. This blog focuses on how this phase-out affects identity and user authentication and discusses alternatives for overcoming challenges.","title":"How Chrome’s Third-Party Cookie Restrictions Affect User Authentication?","tags":["Identity","Cookies","Chrome"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/eb7396060c0adc430dbed2d04b63d431/ee604/third-party-cookies-phaseout-chrome.png","srcSet":"/static/eb7396060c0adc430dbed2d04b63d431/69585/third-party-cookies-phaseout-chrome.png 200w,\n/static/eb7396060c0adc430dbed2d04b63d431/497c6/third-party-cookies-phaseout-chrome.png 400w,\n/static/eb7396060c0adc430dbed2d04b63d431/ee604/third-party-cookies-phaseout-chrome.png 800w,\n/static/eb7396060c0adc430dbed2d04b63d431/f3583/third-party-cookies-phaseout-chrome.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Raghunath Reddy","github":"raghunath-r-a","avatar":null}}}},"pageContext":{"limit":6,"skip":54,"currentPage":10,"type":"//engineering//","numPages":52,"pinned":"17fa0d7b-34c8-51c4-b047-df5e2bbaeedb"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}