{"componentChunkName":"component---src-templates-blog-list-template-js","path":"/engineering/38","result":{"data":{"allMarkdownRemark":{"edges":[{"node":{"excerpt":"Overview   The “reconciliation” algorithm in React is how the decision to re-render the component is made. In the browser, DOM manipulation…","fields":{"slug":"/engineering/reacts-reconciliation-algorithm/"},"html":"<p><strong>Overview</strong>  </p>\n<p>The “reconciliation” algorithm in React is how the decision to re-render the component is made. In the browser, DOM manipulation is expensive and time consuming, both in mounting and unmounting. Part of what makes React very performant is its reconciliation algorithm.  </p>\n<p>In short, it watches closely for differences, and only updates the DOM when necessary and tries to update only the parts which need to be changed.  </p>\n<p><strong>The “Virtual DOM”</strong>  </p>\n<p>The Virtual DOM is a theoretical DOM tree generated by React when a change is made to a component’s state. This is modeled after the state of your application upon modification of the state, for example, after calling this.setState(). React uses what is called a “snapshot” to make this comparison and analysis between the DOM before the update, and the DOM after. This is the point in time when React utilizes its reconciliation algorithm.  </p>\n<p>Updating the Virtual DOM is much faster than the real DOM, since the browser doesn’t need to show a visualization of it.  </p>\n<p><strong>How updates are determined</strong>  </p>\n<p>The reconciliation algorithm is run whenever the component level state is updated. It analyzes the current DOM with the Virtual DOM, in order to determine which changes need to be made to the real DOM. After this step, it has determined which DOM nodes on your application require updates, and it calls the render method.  </p>\n<p><strong>Effect on DOM elements and their attributes</strong>  </p>\n<p>The reconciliation algorithm does not only look at whole DOM elements, it also looks at individual attributes. You can think of the difference as a PUT request vs. a PATCH request, where it only updates the parts which have changed, rather than updating the entire object if there was a change.  </p>\n<p>While it doesn’t unmount and remount the entire element if it doesn’t have to, sometimes it <em>does</em> have to. An example of this would be if you render an element of a different type.  </p>\n<p>Suppose you wanted to switch between two components or elements, perhaps for conditional rendering. This would result in a full unmounting of the component, regardless of whether or not they contain the same child nodes.  </p>\n<p>This differs from switching attributes on the same type of elements, an example of which might be dynamic class names, based on component state. In this scenario, the DOM element is <em>not</em> destroyed, and only the modified attributes are changed. This is useful because it performs minimal operations on the DOM, which as we know, is more resource-intensive than standard object operations.  </p>\n<p><strong>Keys and rerenders</strong>  </p>\n<p>The \"key\" attribute in React can be used to mark whether or not a DOM node is stable. You may have seen a message in the console if you’ve ever attempted to map over a collection and return a JSX element each iteration. This is because the reconciliation algorithm uses the keys to determine if the content has changed, and not including a key may cause unexpected behaviour. For this reason, the keys should be unique so that reconciliation can recognize and identify which elements are stable, and which elements are not.  </p>\n<p>Suppose that you have a list of items, which is derived from an array. If you were to splice an item into the middle of it, that will change all of the indices of the subsequent items. In this scenario, since the keys will not be a stable, unique representation of each item, React can end up mutating the unintended item, which can cause major bugs.  </p>\n<p>A detailed explanation of keys can be found on the official React docs:</p>\n<p><a href=\"https://reactjs.org/docs/lists-and-keys.html\">Lists and Keys</a></p>\n<p><a href=\"https://reactjs.org/docs/reconciliation.html#keys\">Reconciliation-Keys</a></p>\n<p>For an in-depth exploration of how and why reconciliation was implemented, please visit the official React docs:</p>\n<p><a href=\"https://reactjs.org/docs/reconciliation.html\">Reconciliation</a></p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"December 03, 2019","updated_date":null,"description":null,"title":"React's Reconciliation Algorithm","tags":["React"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":2.2988505747126435,"src":"/static/b0ebc3d46b4cf70980708fadb30e73ea/ee604/react-fiber.png","srcSet":"/static/b0ebc3d46b4cf70980708fadb30e73ea/69585/react-fiber.png 200w,\n/static/b0ebc3d46b4cf70980708fadb30e73ea/497c6/react-fiber.png 400w,\n/static/b0ebc3d46b4cf70980708fadb30e73ea/ee604/react-fiber.png 800w,\n/static/b0ebc3d46b4cf70980708fadb30e73ea/31987/react-fiber.png 1000w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Team LoginRadius","github":"LoginRadius","avatar":null}}}},{"node":{"excerpt":"You'll learn about JavasScript NaN in this tutorial, how to check whether a value is NaN, and how to effectively handle NaN. What is NaN in…","fields":{"slug":"/engineering/checking-for-nan-in-javascript/"},"html":"<p>You'll learn about JavasScript NaN in this tutorial, how to check whether a value is NaN, and how to effectively handle NaN.</p>\n<h2 id=\"what-is-nan-in-javascript\" style=\"position:relative;\"><a href=\"#what-is-nan-in-javascript\" aria-label=\"what is nan in javascript permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is NaN in Javascript?</h2>\n<p>NaN, in JavaScript, can be many things. In fact, it can be almost anything, so long as it is <em>Not a Number</em>. Its type is technically “number” (when evaluated with “typeof”), although it stands for <strong>Not a Number</strong>.  </p>\n<h2 id=\"values-in-nan-javascript\" style=\"position:relative;\"><a href=\"#values-in-nan-javascript\" aria-label=\"values in nan javascript permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Values in NaN Javascript</h2>\n<p>Values can become NaN through a variety of means, which usually involve erroneous math calculations (such as 0/0), or as a result of type coercion, either implicit or explicit.</p>\n<p>A common example is when you run parseInt on a string that starts with an alphabetical character. This isn’t exclusive to parseInt, as it also applies when using explicit coercion with Number(), or with the unary “+” operator.  </p>\n<h2 id=\"how-to-check-nan-in-javascript\" style=\"position:relative;\"><a href=\"#how-to-check-nan-in-javascript\" aria-label=\"how to check nan in javascript permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to check NaN in Javascript?</h2>\n<p>Before selecting a method for checking for NaN, <em>how should you</em> <strong><em>not</em></strong> <em>check for NaN?</em></p>\n<p>NaN is a bizarre value in JavaScript, as it does not equal itself when compared, either with the loose equality (==) or strict equality (===) operator. NaN is the only value in the entire language which behaves in this manner with regards to comparisons.  </p>\n<p>For example, if parseInt(“a”) returns NaN, then parseInt(“a”) === NaN will return false. This may seem strange, but it makes perfect sense after thinking about what NaN really is.  </p>\n<p>NaN doesn’t tell you what something is, it tells you what it <strong>isn’t</strong>.  </p>\n<p>These two different strings being passed to parseInt() will both return NaN.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">parseInt</span><span class=\"mtk1\">(“</span><span class=\"mtk12\">abc</span><span class=\"mtk1\">”) </span><span class=\"mtk3\">// NaN</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">parseInt</span><span class=\"mtk1\">(“</span><span class=\"mtk12\">def</span><span class=\"mtk1\">”) </span><span class=\"mtk3\">// NaN</span></span></code></pre>\n<p>Both statements return NaN, but are they <em>really</em> the same? Maybe, but it certainly makes sense why JavaScript would disagree, given that they are derived from different string arguments.  </p>\n<p>Here are a few examples of strict inequality comparisons, which demonstrate the inconsistency of NaN.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk7\">2</span><span class=\"mtk1\"> !== </span><span class=\"mtk7\">2</span><span class=\"mtk1\"> </span><span class=\"mtk3\">// false</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">true</span><span class=\"mtk1\"> !== </span><span class=\"mtk4\">true</span><span class=\"mtk1\"> </span><span class=\"mtk3\">// false</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">“</span><span class=\"mtk12\">abc</span><span class=\"mtk1\">” !== “</span><span class=\"mtk12\">abc</span><span class=\"mtk1\">” </span><span class=\"mtk3\">// false</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">NaN</span><span class=\"mtk1\"> !== </span><span class=\"mtk4\">NaN</span><span class=\"mtk1\"> </span><span class=\"mtk3\">// true</span></span></code></pre>\n<h3 id=\"method-1-isnan-or-numberisnan\" style=\"position:relative;\"><a href=\"#method-1-isnan-or-numberisnan\" aria-label=\"method 1 isnan or numberisnan permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Method 1: isNaN or Number.isNaN</h3>\n<p>JavaScript has a built-in method, appropriately named “isNaN,” which checks for NaN. There is a newer function called Number.isNaN, which is included in the ES2015 spec.  </p>\n<p>The difference between isNaN and Number.isNaN is that isNaN coerces the argument into a number type. To avoid complicated and unexpected outcomes, it is often advised to use the newer, more robust Number.isNaN to avoid these side effects.</p>\n<p>Number.isNaN does not perform any forcible type conversion, so it simply returns the boolean based on the parameter.  </p>\n<p>Here is an example of the difference between the two methods:  </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">isNaN</span><span class=\"mtk1\">(</span><span class=\"mtk4\">undefined</span><span class=\"mtk1\">) </span><span class=\"mtk3\">// true</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">Number</span><span class=\"mtk1\">.</span><span class=\"mtk11\">isNaN</span><span class=\"mtk1\">(</span><span class=\"mtk4\">undefined</span><span class=\"mtk1\">) </span><span class=\"mtk3\">// false</span></span></code></pre>\n<p>isNaN, when passed undefined, returns true because undefined becomes NaN after number coercion. You can test this yourself by running Number(undefined). You will find that it returns NaN.  </p>\n<p>Number.isNaN, on the other hand, returns false. This is because no coercion takes place, and undefined is <em>not</em> NaN, it is simply undefined.  </p>\n<p>It is also important to note that Number.isNaN is a newer (ES2015) <a href=\"https://www.loginradius.com/blog/engineering/16-javascript-hacks-for-optimization/\">method in JavaScript</a>, so browser support for Number.isNaN is not as stable as isNaN, which has been around since ES1 (1997).  </p>\n<h3 id=\"method-2-objectis\" style=\"position:relative;\"><a href=\"#method-2-objectis\" aria-label=\"method 2 objectis permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Method 2: Object.is</h3>\n<p><code>Object.is</code> is a JavaScript method which checks for sameness. It generally performs the same evaluations as a strict equality operator (===), although it treats NaN differently from strict equality.  </p>\n<p><code>Object.is(0, -0)</code> will return false, while 0 === -0 will return true. Comparisons of 0 and -0 differ, as do comparisons of NaN. This concept is called “Same-value-zero equality.”  </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">NaN</span><span class=\"mtk1\"> === </span><span class=\"mtk4\">NaN</span><span class=\"mtk1\"> </span><span class=\"mtk3\">// false</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">Object</span><span class=\"mtk1\">.</span><span class=\"mtk11\">is</span><span class=\"mtk1\">(</span><span class=\"mtk4\">NaN</span><span class=\"mtk1\">, </span><span class=\"mtk4\">NaN</span><span class=\"mtk1\">) </span><span class=\"mtk3\">// true</span></span></code></pre>\n<p><code>Object.is(NaN, NaN)</code> will in fact return true, while we already know that NaN === NaN returns false. That makes this yet another valid way to check if something is not a number.</p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>Between the given methods of checking for NaN, the most common is to use the global isNaN function, or the ES2015 Number.isNaN method. While method #2 is valid, most people will typically use isNaN or Number.isNaN, which were created specifically for checking for NaN.</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 .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n</style>","frontmatter":{"date":"November 22, 2019","updated_date":null,"description":"In this guide you'll learn about JavasScript NaN, how to verify whether a value is NaN, and how to manage NaN effectively.","title":"NaN in JavaScript: An Essential Guide","tags":["JavaScript"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.3333333333333333,"src":"/static/55c8ddd31fa08f811d159c331bf44d5e/2244e/numbers-1.jpg","srcSet":"/static/55c8ddd31fa08f811d159c331bf44d5e/f836f/numbers-1.jpg 200w,\n/static/55c8ddd31fa08f811d159c331bf44d5e/2244e/numbers-1.jpg 400w","sizes":"(max-width: 400px) 100vw, 400px"}}},"author":{"id":"Greg Sakai","github":null,"avatar":null}}}},{"node":{"excerpt":"We're delightfully Announcing SDK Version 10.0.0.  This full-version release includes major changes with several improvements and…","fields":{"slug":"/engineering/sdk-version-10-0-0/"},"html":"<p>We're delightfully Announcing SDK Version 10.0.0. </p>\n<p>This full-version release includes major changes with several improvements and optimizations, the details have been given below. For complete information please visit <a href=\"https://www.loginradius.com/docs/api/\">LoginRadius API documents</a>.</p>\n<h3 id=\"new-features-added\" style=\"position:relative;\"><a href=\"#new-features-added\" aria-label=\"new features added permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>New Features Added:</strong></h3>\n<ul>\n<li><strong>Added PIN Authentication feature APIs.</strong> : We have added the PIN authentication feature. By enabling this feature Customer can provide PIN code for the authorization process. For more details please refer to the <a href=\"https://www.loginradius.com/docs/api/v2/customer-identity-api/authentication/pin-authentication/overview/\">PIN Authentication Document</a>.</li>\n<li><strong>Added Consent Management feature APIs. :</strong> The Consent Management feature allows collecting consent details from the new or existing customers so that you can further use that data.</li>\n<li><strong>Added Local SOTT generation (Secured one-time token):</strong> SOTT is used for LoginRadius user registration via the authentication API or via the Javascript Interfaces. Now SOTT can be generated from the SDK. More detail on SOTT Usage can be seen <a href=\"https://www.loginradius.com/docs/api/v2/customer-identity-api/sott-usage\">here</a>.</li>\n</ul>\n<h3 id=\"improvements-and-optimizations\" style=\"position:relative;\"><a href=\"#improvements-and-optimizations\" aria-label=\"improvements and optimizations permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>Improvements and optimizations:</strong></h3>\n<ul>\n<li>Added internal parameter validations in the API function.</li>\n<li>ApiKey and ApiSecret usage redundancy removed.</li>\n<li>All LoginRadius related features need to be defined once only and SDK will handle them automatically.</li>\n<li>Improved the naming conventions of API functions for better readability.</li>\n<li>Better Error and Exception Handling for LoginRadius API Response in SDK.</li>\n<li>Completely revamped each SDK and restructured them with the latest API function names and parameters.</li>\n<li>Added detailed description to API functions and parameters for better understanding.</li>\n<li>Updated the SDK demos according to the latest SDK changes.</li>\n</ul>\n<h3 id=\"new-apis\" style=\"position:relative;\"><a href=\"#new-apis\" aria-label=\"new apis permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>New APIs:</strong></h3>\n<p>We have added new APIs in this release, that will complement the existing ones.</p>\n<ul>\n<li>Update Phone ID by UID</li>\n<li>Upsert Email</li>\n<li>Role Context profile</li>\n<li>MFA Resend OTP</li>\n<li>User Registration By Captcha</li>\n<li>Get Access Token via Linkedin Token</li>\n<li>Get Access Token By Foursquare Access Token</li>\n<li>Get Active Session By Account Id</li>\n<li>Get Active Session By Profile Id</li>\n<li>Delete User Profiles By Email</li>\n<li>Verify Multifactor OTP Authentication</li>\n<li>Verify Multifactor Password Authentication</li>\n<li>Verify Multifactor PIN Authentication</li>\n<li>Update UID</li>\n<li>MFA Re-authentication by PIN</li>\n<li>Pin Login</li>\n<li>Forgot Pin By Email</li>\n<li>Forgot Pin By UserName</li>\n<li>Reset PIN By ResetToken</li>\n<li>Reset PIN By SecurityAnswer And Email</li>\n<li>Reset PIN By SecurityAnswer And Username</li>\n<li>Reset PIN By SecurityAnswer And Phone</li>\n<li>Forgot Pin By Phone</li>\n<li>Change Pin By Token</li>\n<li>Reset PIN by Phone and OTP</li>\n<li>Reset PIN by Email and OTP</li>\n<li>Reset PIN by Username and OTP</li>\n<li>Set Pin By PinAuthToken</li>\n<li>Invalidate Pin Session Token</li>\n<li>Submit Consent By ConsentToken</li>\n<li>Get Consent Logs</li>\n<li>Submit Consent By AccessToken</li>\n<li>Verify Consent By AccessToken</li>\n<li>Update Consent Profile By AccessToken</li>\n<li>Get Consent Logs By Uid</li>\n<li>Album With Cursor</li>\n<li>Audio With Cursor</li>\n<li>Check-In With Cursor</li>\n<li>Event With Cursor</li>\n<li>Following With Cursor</li>\n<li>Group With Cursor</li>\n<li>Like With Cursor</li>\n</ul>\n<h3 id=\"removed-apis\" style=\"position:relative;\"><a href=\"#removed-apis\" aria-label=\"removed apis permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>Removed APIs:</strong></h3>\n<p>To cope up with the changes around the social platforms, we have removed some existing APIs as they are no longer supported by the social providers. Below are the details of those APIs.</p>\n<ul>\n<li><strong>GetCompanies API:</strong> This API was used to get the list of companies from social sites. we removed this API because it is not supported by the social providers</li>\n<li><strong>Getstatus API:</strong> This API was used to get the status from social sites.</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":"October 31, 2019","updated_date":null,"description":null,"title":"SDK Version 10.0.0","tags":["Engineering","SDK","Version"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.3333333333333333,"src":"/static/88ba5be9965365e5417420f1910d9c33/497c6/SDK.png","srcSet":"/static/88ba5be9965365e5417420f1910d9c33/69585/SDK.png 200w,\n/static/88ba5be9965365e5417420f1910d9c33/497c6/SDK.png 400w","sizes":"(max-width: 400px) 100vw, 400px"}}},"author":{"id":"Indrasen Kumar","github":"indrasen715","avatar":null}}}},{"node":{"excerpt":"This blog is part 1 of a series on gRPC. Part 1 will go over some important concepts, part 2 will be a walkthrough of a client-server…","fields":{"slug":"/engineering/getting-started-with-grpc-part-1-concepts/"},"html":"<p><em>This blog is part 1 of a series on gRPC. Part 1 will go over some important concepts, part 2 will be a walkthrough of a client-server implementation in Go, and part 3 will be about LoginRadius' experience migrating to gRPC!</em></p>\n<p><strong>gRPC</strong></p>\n<p>gRPC, simply put, is just another way to send data across networks. It can be used to communicate between services in a microservice architecture, where a single service can interact with multiple others. Similarly, in client-server models, there can be multiple clients communicating with a common backend server.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 281px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 108.54092526690391%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAWCAYAAADAQbwGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACnklEQVQ4y6VUW2sTURDOP/KHifgmCAUfvCAqeIGCz4pgKahQJKFSawWt3dLUhrSb0GSzTdo07W6yt+x9z37unM1u0jTRgAPDmT2Z+TJz5pspYEriOOanYRiQJAm9Xg/dbpdrp9NBu93m977vX/HPpDAP0LIsiKKIZrOJer3O7VarhVqthoODg8UBZznNk8xv0r8w7TDpxBi7pnGiACn5cs//z/DbRYxqn3GbxQtmGIYhf6dMXc9HHHromAy3V/t4/73P/SKWZToHkIQAqLuapmEwGMA0TeiGCX+oYVv2cONWBfdf700Axn8HtG2bg2RCtpEAUobnFvDyYxflSit5z/DfTSFxHIfzMCu9UqlAEATOwUzsoQnP8xcDpAyp3NkNS09FUREEcwCn+UT0oLdTVZXr5eUlZFnOvxVF4RVkTZyMLyxCFfqNgBYh+bUMPc+D67pcyc6+aZY5fUb3mQ/dXcswXwimhfPeBXTd4G+o6zrXwUDjC2Hynk4qm+hFwDlgCpYCBk5ClcidWZKhz26SPbR4E69k6AUxxGScypIBoWmhfsEQRCzNPNEgZJDPFP630404V3XYCc3SMRwB7ndCPPni4NWmi3eCh8frDppKlGdBdrHqwPLinDoU/ONYw4O1BpY3TnCiOuOm7J2EKB76WN5ysXUcYF0McNgdAzYSwP3TCJrD8ueRlSHurIh4Wmph6cMxnpcaY8DfpyEelhy8+eXhxVcX9z7baKnRKDhGZxBho+7D9lNANir3WVHC3dUabr6tYuNIHQPSgG9LIZbWbDxKgCtn4UJLdvOwh09CGys/ZTR6Vgo4OzC9OzoSsbOzA2F3F42mhL1yGdVqNRm5YC65C5N7kLG0nKwk2jI0dqRk9/t9zsEoivLVlWkW8wfurJ+AZ2SlUAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Screen Shot 2019 10 30 at 1 31 52 PM\"\n        title=\"Screen Shot 2019 10 30 at 1 31 52 PM\"\n        src=\"/static/d43dcaf192be0d2c6332422eaa55f4f2/6b1e2/Screen-Shot-2019-10-30-at-1.31.52-PM.png\"\n        srcset=\"/static/d43dcaf192be0d2c6332422eaa55f4f2/6b1e2/Screen-Shot-2019-10-30-at-1.31.52-PM.png 281w\"\n        sizes=\"(max-width: 281px) 100vw, 281px\"\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>The gRPC framework was initially developed at Google and is now open-source. It is a modern implementation of the RPC (Remote Procedure Call) protocol, which has been around since the 80s. You will often see gRPC being compared to other technologies like SOAP, REST, and GraphQL.</p>\n<p>Some features:</p>\n<ul>\n<li>HTTP/2 based transport</li>\n<li>Unary calls: single request, single response</li>\n<li>Streaming calls: client, server, and bidirectional</li>\n<li>Layered design for further extension e.g. authentication, load balancing, logging</li>\n</ul>\n<p><em>How is it used to send data?</em></p>\n<p>gRPC is based on the idea of calling a remote procedure just like a local one. A procedure is like a function or a method. So, ideally developers can treat remote and local calls similarly. A great thing about gRPC is that developers do not need to know the details of the remote interaction.</p>\n<p>Here is a diagram from the official grpc <a href=\"https://grpc.io/docs/guides/\">docs</a> showing the flow:</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: 62.46153846153847%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAACh0lEQVQoz3WT+09ScRjG+Uv6rT+g5Q+1ZdkyyQC1ixO1LJzl5hK3Wv1WtvKCm23NVatYmqagycXIazW31BWWFcsmkty8IFJyFBEEuTy950uYkb3bs+85O+d89jzv+x4BtlU8HmdKXvMVDIVgW3DB7HBiyesF5/OBWw/ghrYHBTV1OPe4GRd7X+HCiwFU9r+GgP8oGov9pUg0ymBrgQA+T1sw63bDQ7Cl5WV4SG7fGgrrGpAulWLf5as42q5BZmsnjrd3Q5B0klrrBLPOzyO2w/ONzU3IlC1Ir1FAeF8JiVoHUYcGJzv1CYeDZguevTNCZfwA9fhHNL8dQ/vI2B9AKMzc2l0uzMzNwU4tqOgdQpZKBwlBeGe88gjMgMKbt7E7Nw9pJeexp/gsdokkKGhohG8jxCJOWm0wWb6T4wX4CcyXfOANxAQp0fWS+hgsNwnMv3MXaaVlOHhJjgx5FfbKSnG6VgGT1QorOfKurv4T20V9tHk5OLgV2LlV2Oh0rvgSwDKa0JEWFbLbupgOK9tQpTWw4fBTnXbO4ovFgm/k1P1zGaFwGGHqrT8SRYDeCVBPeW1EIgmgVGNAxlM1xCots53R2oUzKg0WPJ4tRzzEw3Fs2i5SZXMrcq5X41TTAxRT5MJuA2Q9/QngowkTFKNGNBkncG/8E+pH3qNjcgo/CGB2ONgZo3ViYNpLF8XLv1WLQ0VF2H/lGoQdWmRRMjFN+r9rkywvRZ6yO/B1ZobFdi4uwuv3o+K5HgfqG3Hs4ROWTEQDOpFcm2gs/nup42zv+OvYtr8mGdkfDG7dyweHkUnOxNQifmWySTkEFuzkKvUXTE2xSYOoHh6FTN+HcsMgG2r5yyGU0vkLJegoPEJ8Il4AAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Screen Shot 2019 10 30 at 1 35 45 PM 768x480\"\n        title=\"Screen Shot 2019 10 30 at 1 35 45 PM 768x480\"\n        src=\"/static/a8b70d1d23742fa9aae6c6d2791775c6/e5715/Screen-Shot-2019-10-30-at-1.35.45-PM-768x480.png\"\n        srcset=\"/static/a8b70d1d23742fa9aae6c6d2791775c6/a6d36/Screen-Shot-2019-10-30-at-1.35.45-PM-768x480.png 650w,\n/static/a8b70d1d23742fa9aae6c6d2791775c6/e5715/Screen-Shot-2019-10-30-at-1.35.45-PM-768x480.png 768w\"\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>Each client service will include a stub, which is like an interface containing the available remote procedures. These stubs are auto-generated files.</p>\n<p><em>But what does proto refer to? And what are stubs? How can we generate them?</em></p>\n<p>To answer these questions, we need to look at another technology called protocol buffers.</p>\n<p><strong>Protocol Buffers</strong></p>\n<p>Protocol buffers (protobufs), are a way to format data for storage and transport. gRPC uses protobufs to format data sent over the wire. It is comparable to other data serialization formats such as JSON, XML, and YAML.</p>\n<p>Some features:</p>\n<ul>\n<li>\n<p>Ability to generate interfaces (stubs) for many languages</p>\n<ul>\n<li>You can create proto definitions once (in a .proto file), and compile it into a variety of different languages including Go, Java, C#, and Python.</li>\n</ul>\n</li>\n<li>\n<p>Requires defining schemas - need to know expected data fields and types</p>\n<ul>\n<li>This is unlike JSON which is flexible.</li>\n</ul>\n</li>\n<li>\n<p>Binary format, meaning data is converted into binary when sent over the wire.</p>\n<ul>\n<li>Binary is smaller, and generally can be decoded faster compared to text-based formats such as JSON.</li>\n</ul>\n</li>\n</ul>\n<p><em>How is it used with gRPC?</em></p>\n<p>Step 1: Create proto definitions - methods, requests, responses.</p>\n<ul>\n<li>For example, in account.proto file, we define 3 rpc methods: Find, Update, and Delete.</li>\n<li>These are the remote procedures that can be called by clients.</li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"protobuf\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">service AccountService {</span>\n<span class=\"grvsc-line\">  rpc Find(FindRequest) returns (FindResponse);</span>\n<span class=\"grvsc-line\">  rpc Update(UpdateRequest) returns (UpdateResponse);</span>\n<span class=\"grvsc-line\">  rpc Delete(DeleteRequest) returns (DeleteResponse);</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<ul>\n<li>Each method can have its own request and response schemas.</li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"protobuf\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">message FindRequest {</span>\n<span class=\"grvsc-line\">  string Uid = 1;</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">message FindResponse {</span>\n<span class=\"grvsc-line\">  string Uid = 1;</span>\n<span class=\"grvsc-line\">  string Name = 2;</span>\n<span class=\"grvsc-line\">  int32 Age = 3;</span>\n<span class=\"grvsc-line\">  bool isVerified = 4;</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<ul>\n<li>Note that each field in a message has a unique number. These numbers are used to identify the fields when encoded into binary (recall that protobuf sends data over the wire as binary).</li>\n</ul>\n<p>Step 2: Compile proto file for auto-generated stubs in desired language.</p>\n<ul>\n<li>First, the compiler needs to be <a href=\"https://github.com/protocolbuffers/protobuf\">installed</a>. Refer to blog <em>part 2</em> for detailed instructions.</li>\n<li>The compiler is invoked by the protoc command. In this case, the file account.proto is compiled into Golang with a grpc plugin.</li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"batch\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">protoc account.proto --go_out=plugins=grpc:.</span></span></code></pre>\n<ul>\n<li>Different languages may have different ways of compiling proto files. For instance with NodeJS, there are npm libraries which allow programmatically compiling proto files.</li>\n</ul>\n<p>Step 3: Use stubs in server and clients.</p>\n<p><strong>The Big Picture</strong></p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 387px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 92.24806201550389%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAACXBIWXMAAAsTAAALEwEAmpwYAAABw0lEQVQ4y3XUhwrjQAwE0Pz/N4YEEkhI7734eIIxG+5OsPZabUcjeQfP57O73W61zudzNx6Pu9lsVt/X67Xe7/e7I76j4zMajbrD4dDHPx6PbuBxv9+77XZbCR1AdzqdylmCJKTf7/fd8XisPf3lcik/S+ygRUim02ktwmYvqf1iseg2m03Z7IfDYfd6verbQX1CAbvdrhSQWkFpL+j7/da3hPwksA8F/CqhQAHKVfpqtSojJ+XEnpLDoxKhDPdii0Mbp0c4JAHBk5MJ3wif0ETkYC+En8+nJx46pHOgF9gmjB769Xpd32LpCiHntsu4VA6+8CQwiCFidyAf9kwD3U+X8UKWy2XxmC4LaudQIHGQCQhdf3UZOiIgQZm7JMzMxaYqCa1MSd9lgZLqHG6UIjE6UrJ99JLN5/OfH+CfXebQdu9/XebDNx3uu+yhQy0XkMYpXU5A9MpXJhH/0+XwkW6nBO8cmCbROdDyp0CaqfhpikCcWG6S/H6TyaRHTQ8VdG4lfPNXhaQ9wlwOmiGYY24Pe4fhMkMvodGC0JglYd9lyRjTwbyhaa+vDHZKjG90hRA/4TFI2wuTreWwrShLBfSQ/gE1JnSTwHNvmgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Screen Shot 2019 10 30 at 1 57 55 PM\"\n        title=\"Screen Shot 2019 10 30 at 1 57 55 PM\"\n        src=\"/static/729430686438f756b74979321b48537d/691c3/Screen-Shot-2019-10-30-at-1.57.55-PM.png\"\n        srcset=\"/static/729430686438f756b74979321b48537d/691c3/Screen-Shot-2019-10-30-at-1.57.55-PM.png 387w\"\n        sizes=\"(max-width: 387px) 100vw, 387px\"\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><strong>Why gRPC?</strong></p>\n<p>One compelling reason to use gRPC is that it provides high performance</p>\n<ul>\n<li>HTTP/2: e.g. requests are multiplexed, so a single long-lived TCP connection can be used by multiple requests at once. This results in less connection overhead.</li>\n<li>Protobufs: e.g. as a binary format, it allows for quick encoding and decoding of data. </li>\n</ul>\n<p><em>How does it differ from REST?</em></p>\n<table>\n<thead>\n<tr>\n<th></th>\n<th><strong>gRPC</strong></th>\n<th><strong>REST</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>API</td>\n<td>Contract-based i.e. stubs</td>\n<td>Resource-based and relies on HTTP verbs i.e. GET/PUT/POST/DELETE</td>\n</tr>\n<tr>\n<td>Network protocol</td>\n<td>HTTP/2</td>\n<td>HTTP/1.1 or HTTP/2</td>\n</tr>\n<tr>\n<td>Data serialization format</td>\n<td>Protocol buffers</td>\n<td>JSON</td>\n</tr>\n<tr>\n<td>Streaming</td>\n<td>Built-in support for client, server, and bi-directional streaming</td>\n<td>REST on HTTP/1.1 does not allow streaming</td>\n</tr>\n</tbody>\n</table>\n<p><strong>Other Considerations</strong></p>\n<p>Here, we briefly go over a few other things to consider with gRPC. These will be covered in more detail in another blog.</p>\n<p><em>Management of proto files</em><br>\nIf you plan to have multiple proto files and client services, you need some way to manage them for distribution and version control. One solution is to keep all proto files in a central git repository, and maintain versions using git tags.</p>\n<p><em>Using proto2 vs. proto3</em><br>\nProtocol buffers have two syntax versions: proto2 and proto3.</p>\n<ul>\n<li>One key feature in proto2 is that it differentiates between required and optional fields, and supports nullable fields.</li>\n<li>In proto3, all fields are optional and nullable fields are no longer supported. If a field is unset, it will be set to a default value e.g. empty string for type string. Because of this, determining whether a field was intentionally set or not requires workarounds such as using wrappers.</li>\n</ul>\n<p><em>Load-Balancing</em><br>\nSomething to note about load-balancing gRPC is that HTTP/2 requires L7 (Application Layer) load-balancers. Recall that in HTTP/2, TCP connections are long-lived and requests are multiplexed. This makes L4 (Connection Layer) load-balancers ineffective. This differs from HTTP/1.1 where TCP connections get cycled and can benefit from L4 load-balancers. </p>\n<p>That's it for now! To learn more, check out the official <a href=\"https://grpc.io\">gRPC</a> and <a href=\"https://developers.google.com/protocol-buffers\">protobuf</a> docs.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n</style>","frontmatter":{"date":"October 30, 2019","updated_date":null,"description":null,"title":"Getting Started with gRPC - Part 1 Concepts","tags":["Engineering","gRPC"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/ceff66d5b341e58e4b85f5a6c3a7cbad/f006c/grpc.png","srcSet":"/static/ceff66d5b341e58e4b85f5a6c3a7cbad/69585/grpc.png 200w,\n/static/ceff66d5b341e58e4b85f5a6c3a7cbad/f006c/grpc.png 246w","sizes":"(max-width: 246px) 100vw, 246px"}}},"author":{"id":"Andy Yeung","github":null,"avatar":null}}}},{"node":{"excerpt":"Introduction Cross-Site Request Forgery (CSRF) is a common web application attack where a victims’ authenticated session becomes compromised…","fields":{"slug":"/engineering/introduction-to-cross-site-request-forgery-csrf/"},"html":"<p><strong>Introduction</strong></p>\n<p>Cross-Site Request Forgery (CSRF) is a common web application attack where a victims’ authenticated session becomes compromised. This attack essentially tricks a victim into performing unintended tasks on a website they are authenticated in. There are variations to this attack, and a popular one we will discuss is utilizing authentication token to imitate api requests.</p>\n<p><strong>Context</strong></p>\n<p>In order to understand CSRF, it is important to know how cookies and authentication tokens are used for persisting user sessions. Cookies are information stored in the browser, and often used for managing state between HTTP requests. A key feature of cookies is that they are automatically passed as a header in HTTP requests. Authentication tokens are typically stored as cookies, and are a way to keep track of a users’ authenticated session. These tokens are set as cookies after a user successfully authenticates themselves by log in.</p>\n<p><strong>How it works</strong></p>\n<p>CSRF takes advantage of the storage of auth tokens in the browser, and constructs http requests to a target server on behalf of the user. Imitating http requests from the legitimate site requires research and preparation from the attacker beforehand, such as finding vulnerable websites and api’s suitable for the attack.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 606px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 56.76567656765676%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAABB0lEQVQoz4WTiQrEMAhE8/+/WSj0vu8jyxMmZLvLriBaY8bRWHddlz/P02NjH7nv2yzf67r64zjM7vtuPlaqM8cHINht24IvMAESQ4qisDwVlCLEnRLnefZN05hPNbEUIDFkGAYrGncgC1YAhO44jH8By7I00HgsXwGnafrJUHMCsK7rj7ZDywCRwGy6rgsHxBnDsiy+bVvf973lAUhhzuM5vzHkImAk4gMYJ+MTs7GMo7VMnjYD5ijFHQ5AeZ4bKAy4+HxlPQRMVTxJEp+mqVnFnfYKdBQmaDxDwDmDHW3DUPekoeV4qePlfq4EYFmWGYuqqmyuTzFA/0PiP0XM9VCMisJS5bwAS0depIUcuKgAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"image2\"\n        title=\"image2\"\n        src=\"/static/b83e1bb3840acfc8b1162e6263c5df22/4d4a2/image2.png\"\n        srcset=\"/static/b83e1bb3840acfc8b1162e6263c5df22/4d4a2/image2.png 606w\"\n        sizes=\"(max-width: 606px) 100vw, 606px\"\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>Here is a high-level example of an CSRF attack. Note that some details are excluded for simplicity, but the key aspects are included.</p>\n<ol>\n<li>\n<p>John is authenticated on banking.io</p>\n<ul>\n<li>Auth token is set as a cookie on the browser.</li>\n</ul>\n</li>\n<li>\n<p>On another tab, John clicks on an advertisement for free money, which leads to a malicious site.</p>\n<ul>\n<li>Typically, some social engineering is necessary to lure victims to a malicious website.</li>\n</ul>\n</li>\n<li>\n<p>Malicious site makes a POST request to banking.io/setpassword, which is an api for setting a users password to anything.</p>\n<ul>\n<li>The malicious site will construct the POST request for setting password exactly like the legitimate site, and uses John’s authentication cookie.</li>\n<li>The password will be set to anything the attacker wants.</li>\n</ul>\n</li>\n<li>Victim is unable to authenticate with banking.io anymore, because the password was set to something else.</li>\n</ol>\n<p><strong>Mitigation</strong></p>\n<p>A common and effective way of mitigating CSRF is called the double submit cookie. Essentially the client will have two paired and encrypted tokens: one hidden in the page HTML and the other stored as a cookie.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 362px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 69.06077348066299%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAABV0lEQVQ4y5WUi66CMAyG9/6PR6LcjKJBoyKCeEHwUvM1GdnhcNSzpGm3tf/6twUjzno+n519uVzkcDhIVVWqr9dr5+P69ZdxwawjIH0AHjifzx9BTT+7pmmkKArJskyF7PI8l/V6ree32+0Xm7eAbdtqIFlaTWbYyP1+/5FlX4y7eTwe6lyWpQp7BJAkSRT80zJDh9Am2DaGeu52O6Ve17UKPmh8uIcFtiFgu93Kfr9XgdZqtdIAd+Ecx7F4niez2UzCMJTRaNTZ4/FY62ygttlspCgLBSSL5XLZAdrakg1NCoJAojiSKIrE931ZLBYymUz0nJhBylA4nU5aP5qEtpTYE0i38bM2D1LrwaaQ+nw+VwBqCTgsCPq6KZYar0DdrSF3ZEZ5/hqXbmyGBpuOTqdTLTjZpmmqjQIQ4H8NNrTdwP63/fWn1weldgAzRujj8djdv/s5vAAlG0QDj7T1eQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"image1\"\n        title=\"image1\"\n        src=\"/static/d77ad92ba64b2cbbd3e711289b8a6750/10600/image1.png\"\n        srcset=\"/static/d77ad92ba64b2cbbd3e711289b8a6750/10600/image1.png 362w\"\n        sizes=\"(max-width: 362px) 100vw, 362px\"\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>When a request is made by the client, both tokens are sent to the server, and the server will then ensure the tokens are valid pairs before processing the request as normal. </p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 360px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 68.61111111111111%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAABVElEQVQ4y5WU666CQAyEef9n868aQRMiclMBr9yx5muyBBHMOZs0S0p3djpTsGRivV4v3buuk9vtJpfLRa7Xq+7P5/OrbrisX2BZlknbth/5oijkfr/3uTHoLCBMYOX7voRhKEmS6B4EgTLlwimWs4BlWerBPM+VFUEOduRN3RegoT0OFqxoG7CqqnS3bVsej8dHy8Ow5MfiYNM0CsYzenLJlBk9Q4qjOFJ94jiW8/ksx+NRme12O9VsCJCmqepKLe+oV23DQOWwEJeC1Woly+VSNpuNbLdbBVssFspoqBVGAeI4jra/Xq/1ee/ttZu+ZYAJ2jKHYYNu5Oq61h3AocPkzGj1psw5fTgclD1OM+DoGEWRajp2+MOUKYc5hI6GGXmYMTrk5ybj52CfTidxXVcD3TzPUzMA/Pdgw4oBRujhOy6i/T9/emNQTCDMT8IM9dzP4Q2SS0UPJo5/RQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"image3\"\n        title=\"image3\"\n        src=\"/static/849c7d576c91bbfd334eee6ffbdf0853/f21e7/image3.png\"\n        srcset=\"/static/849c7d576c91bbfd334eee6ffbdf0853/f21e7/image3.png 360w\"\n        sizes=\"(max-width: 360px) 100vw, 360px\"\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 the attacker will be unable to perform CSRF since they will not have access to the token hidden in the pages HTML, and the target server requires a valid token pair before processing the request.</p>\n<p>There are also many other mitigation techniques, such as using the Same-Site cookie attribute, and requiring user interaction such as CAPTCHA for requests. Learn more on the <a href=\"https://owasp.org/www-community/attacks/csrf\">OWASP wiki</a>).</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"October 30, 2019","updated_date":null,"description":null,"title":"Introduction to Cross-Site Request Forgery (CSRF)","tags":["CSRF"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.3333333333333333,"src":"/static/4a13eeb54334febf9c8db79b24424eb6/2244e/crosspath.jpg","srcSet":"/static/4a13eeb54334febf9c8db79b24424eb6/f836f/crosspath.jpg 200w,\n/static/4a13eeb54334febf9c8db79b24424eb6/2244e/crosspath.jpg 400w","sizes":"(max-width: 400px) 100vw, 400px"}}},"author":{"id":"Andy Yeung","github":null,"avatar":null}}}},{"node":{"excerpt":"What is Web Accessibility? Web Accessibility (often stylized “a11y”), is the practice of ensuring that your websites and web applications…","fields":{"slug":"/engineering/introduction-to-web-accessibility-with-semantic-html5/"},"html":"<p><strong>What is Web Accessibility?</strong></p>\n<p>Web Accessibility (often stylized “a11y”), is the practice of ensuring that your websites and web applications are accessible by people with disabilities of many kinds.</p>\n<p>Some examples of common disabilities which we need to consider are: Blindness and visual impairment, deafness and hearing difficulties, motor skill impairment, and many more.</p>\n<p>The common categories of disabilities include:</p>\n<ul>\n<li>Auditory</li>\n<li>Cognitive, learning, and neurological</li>\n<li>Physical</li>\n<li>Speech</li>\n<li>Visual</li>\n</ul>\n<p><em>This list was taken from the W3C Web Accessibility Initiative (WAI). A link to their resources can be found at the bottom.</em></p>\n<p><strong>What is Semantic HTML? What is its correlation with Web Accessibility?</strong></p>\n<p>HTML semantics refers to conveying meaning through the use of HTML elements. An example of <em>semantic</em> HTML would be using <strong><code>&#x3C;header></code></strong>, <strong><code>&#x3C;main></code></strong>, <strong><code>&#x3C;footer></code></strong>, and other content-specific tags when applicable. <em>Unsemantic</em> HTML would be using <strong><code>&#x3C;div></code></strong> or <strong><code>&#x3C;span></code></strong> tags for every use-case.</p>\n<p><strong>Images and “alt” attributes</strong></p>\n<p>Users who are visually impaired may encounter trouble when the content of a website relies on an image. Luckily, there are precautions that we - as developers - can take to ensure that their user experience does not suffer because they are unable to see images.</p>\n<p>The easiest way to do this is to add an <strong>alt</strong> attribute to <strong>all</strong> of your <strong><code>&#x3C;img></code></strong> tags. This way, screen readers will be able to describe the image to the user. Here are a few suggestions and best practices for writing <strong>alt</strong> text:</p>\n<ul>\n<li>\n<p><strong>Do not include words like “image”, or “picture”.</strong> It is redundant, because the screen reader will notify the user that it’s an image. An exception to this would be if the image is of a painting, or an illustration. In this case, emphasizing that is fine, because you want the user to know that it’s specifically a painting, as opposed to any image.</p>\n<ul>\n<li>Example: <strong>alt=”Painted portrait of Albert Einstein”</strong></li>\n</ul>\n</li>\n<li>\n<p><strong>Always include the alt attribute</strong>, even if you don’t want the screen reader to read it. If you have a decorative image (one that is simply cosmetic, and not necessary for the site), then you can add an <strong>alt</strong> tag and assign it to an empty string. In this case, the image will be ignored by the screen reader. If this is neglected, the screen reader may read the file name instead, which may not be particularly helpful.</p>\n<ul>\n<li>Tip: you can also assign an attribute of <strong>role=”presentation”</strong> for decorative images. This can be done in addition to the alt attribute.</li>\n</ul>\n</li>\n<li><strong>Keep it concise.</strong> While there is no limit for length of <strong>alt</strong> text, some screen readers will cut off the alt text at around 125 characters. Either way, you don’t want to waste the user’s time by having their screen reader read a needlessly long description.</li>\n</ul>\n<p><strong>Form Labels and ARIA Labelling</strong></p>\n<p>Users with screen readers will need some way to differentiate between multiple inputs on a single form. Without labels, the user will have a difficult time figuring out what each input is for.</p>\n<p>The easiest way to implement form labelling is with the HTML <strong><code>&#x3C;label></code></strong> tag. The <strong><code>&#x3C;label></code></strong> element uses an attribute called <code>for</code> in order to form a relationship with the ID of the <strong><code>&#x3C;input></code></strong> tag.</p>\n<p>Another way to give context to a screen reader is with the ARIA <strong><code>aria-labelledby</code></strong> attribute. This attribute can be placed on (but not limited to) <strong><code>&#x3C;input></code></strong> tags, and then reference the <strong>id</strong> of the label. You can use <strong><code>&#x3C;label for=””></code></strong> in conjunction with <strong><code>&#x3C;input aria-labelledby=””></code></strong> in order to provide extra support and maximize compatibility.</p>\n<p><strong>Buttons and Tabindices</strong></p>\n<p>Buttons should use <strong><code>&#x3C;button></code></strong> tags (or <strong><code>&#x3C;input type=”submit”></code></strong> if applicable), rather than <strong><code>&#x3C;a></code></strong>, <strong><code>&#x3C;span></code></strong>, <strong><code>&#x3C;div></code></strong>, or anything else that doesn’t have semantic meaning for clickable buttons. Often people choose to use these tags, because they want to clear all styling and not have default <strong><code>&#x3C;button></code></strong> styling. This is ill-advised because <strong><code>&#x3C;button></code></strong> tags come with a ton of functionality built-in, an important part being its <strong><code>tabindex</code></strong>. A user who isn’t able to use a mouse, and must navigate the site with their keyboard, will press the <strong><code>tab</code></strong> key to jump through interactive elements. Standard <strong><code>&#x3C;div></code></strong> tags are not tabbable by default, and assigning a <strong><code>tabindex</code></strong> to it manually can break the flow of the natural tabindices of the page.</p>\n<p><strong>Other Semantic HTML tags</strong></p>\n<p>Other than images and forms, there are still many ways to provide the best accessibility possible. Semantic HTML tags are useful because they describe the content and the relationship with your overall page. Using appropriate, accurate tags such as <strong><code>&#x3C;article></code></strong>, <strong><code>&#x3C;aside></code></strong>, <strong><code>&#x3C;section></code></strong> will give screen readers an idea of what the role is for those sections.</p>\n<p>Other elements such as <strong><code>&#x3C;h1></code></strong> and other heading tags should be carefully planned before sprinkled throughout your webpage. The <strong><code>&#x3C;h1></code></strong> through <strong><code>&#x3C;h6></code></strong> tags should form direct relationships with each other in order to differentiate their meaning. Headings with lower importance (relative to the previous heading) can be used to start new subsections within its current section. Your different page sections can even use <strong><code>aria-labelledby</code></strong> to point to its corresponding heading in order to label your sections accurately.</p>\n<p>The full W3C specification on HTML semantics can be found at: <a href=\"https://www.w3.org/TR/2016/REC-html51-20161101/dom.html\">W3C Recommendation</a>.</p>\n<p>More information about the varying disabilities and barriers can be found at: <a href=\"https://www.w3.org/WAI/people-use-web/abilities-barriers/\">Diverse Abilities and Barriers</a></p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"July 24, 2019","updated_date":null,"description":null,"title":"Introduction to Web Accessibility with Semantic HTML5","tags":["HTML5","HTML","Web Accessibility","Semantic HTML5"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/f3092adaa3def7fb943a47f7a5c8be4c/ee604/handicapped.png","srcSet":"/static/f3092adaa3def7fb943a47f7a5c8be4c/69585/handicapped.png 200w,\n/static/f3092adaa3def7fb943a47f7a5c8be4c/497c6/handicapped.png 400w,\n/static/f3092adaa3def7fb943a47f7a5c8be4c/ee604/handicapped.png 800w,\n/static/f3092adaa3def7fb943a47f7a5c8be4c/a8378/handicapped.png 1024w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Greg Sakai","github":null,"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":222,"currentPage":38,"type":"//engineering//","numPages":52,"pinned":"17fa0d7b-34c8-51c4-b047-df5e2bbaeedb"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}