{"componentChunkName":"component---src-templates-blog-list-template-js","path":"/engineering/39","result":{"data":{"allMarkdownRemark":{"edges":[{"node":{"excerpt":"A basic example of a JavaScript event Events, in JavaScript, are occurrences that can trigger certain functionality, and can result in…","fields":{"slug":"/engineering/javascript-events-bubbling-capturing-and-propagation/"},"html":"<p><strong>A basic example of a JavaScript event</strong></p>\n<p>Events, in JavaScript, are occurrences that can trigger certain functionality, and can result in certain behaviour. A common example of an event, is a “click”, or a “hover”. You can set listeners to watch for these events that will trigger your desired functionality.</p>\n<p><strong>What is “propagation”?</strong></p>\n<p>Propagation refers to how events travel through the Document Object Model (DOM) tree. The DOM tree is the structure which contains parent/child/sibling elements in relation to each other. You can think of propagation as electricity running through a wire, until it reaches its destination. The event needs to pass through every node on the DOM until it reaches the end, or if it is forcibly stopped.</p>\n<p><strong>Event Bubbling and Capturing</strong></p>\n<p>Bubbling and Capturing are the two phases of propagation. In their simplest definitions, <strong>bubbling</strong> travels from the <em>target</em> to the <em>root</em>, and <strong>capturing</strong> travels from the <em>root</em> to the <em>target</em>. However, that doesn’t make much sense without first defining what a target and a root is.</p>\n<p>The <em>target</em> is the DOM node on which you click, or trigger with any other event.</p>\n<p>For example, a button with a click event would be the event target.</p>\n<p>The <em>root</em> is the highest-level parent of the target. This is usually the <strong>document</strong>, which is a parent of the <strong><body></strong>, which is a (possibly distant) parent of your target element.</p>\n<p>Capturing is not used nearly as commonly as bubbling, so our examples will revolve around the bubbling phase. As an option though, <strong>EventTarget.addEventListener()</strong> has an optional third parameter - which takes its argument as a boolean - which controls the phase of the propagation. The parameter is called <strong>useCapture</strong>, and passing <strong>true</strong> will cause the listener to be on the capturing phase. The default is <strong>false</strong>, which will apply it to the bubbling phase.</p>\n<p>Once you trigger the event, it will <em>propagate</em> up to the root, and it will trigger every single event handler which is associated with the same type. For example, if your button has a click event, during the bubbling phase, it will bubble up to the root, and trigger every click event along the way.</p>\n<p>This kind of behaviour might not sound desirable - and it often isn’t - but there’s an easy workaround...</p>\n<p><strong>Event.stopPropagation()</strong></p>\n<p>These two methods are used for solving the previously mentioned problem regarding event propagation. Calling <strong>Event.stopPropagation()</strong> will prevent further propagation through the DOM tree, and only run the event handler from which it was called.</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=\"mtk1\">&lt;!--</span><span class=\"mtk12\">Try</span><span class=\"mtk1\"> </span><span class=\"mtk12\">it</span><span class=\"mtk1\">--&gt;</span></span></code></pre>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">first</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=\"mtk7\">1</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">second</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=\"mtk7\">2</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">button</span><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\">&quot;button&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">container</span><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\">&quot;container&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">button</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addEventListener</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;click&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">first</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">container</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addEventListener</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;click&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">second</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>In this example, clicking the button will cause the console to print <strong>1, 2</strong>. If we wanted to modify this so that <em>only</em> the button’s click event is triggered, we could use <strong>Event.stopPropagation()</strong> to immediately stop the event from bubbling to its parent.</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\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">first</span><span class=\"mtk1\">(</span><span class=\"mtk12\">event</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">event</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stopPropagation</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=\"mtk7\">1</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>This modification will allow the console to print <strong>1</strong>, but it will end the event chain right away, preventing it from reaching <strong>2</strong>.</p>\n<p><strong>How does this differ from <code>Event.stopImmediatePropagation()</code>? When would you use either?</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!--</span><span class=\"mtk12\">Try</span><span class=\"mtk1\"> </span><span class=\"mtk12\">it</span><span class=\"mtk1\">--&gt;</span></span></code></pre>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">first</span><span class=\"mtk1\">(</span><span class=\"mtk12\">event</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=\"mtk7\">1</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">second</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=\"mtk7\">2</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">third</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=\"mtk7\">3</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">button</span><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\">&quot;button&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">container</span><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\">&quot;container&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">button</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addEventListener</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;click&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">first</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">button</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addEventListener</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;click&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">second</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">container</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addEventListener</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;click&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">third</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>Let’s suppose we wanted to add a third function, which prints <strong>3</strong> to the console. In this scenario, we will also move the <strong>second</strong> function to also be on the button. We will apply <strong>third</strong> to the container now.</p>\n<p><strong>Long story short</strong>: we have two event handlers on the button, and clicking <strong>&#x3C;div#container></strong> will now print <strong>3</strong>.</p>\n<p>What will happen now? This will behave the same as before, and it will propagate through the DOM tree, and print <strong>1, 2, 3</strong>, in that order.</p>\n<p><strong>How does this tie in to <code>Event.stopPropagation()</code> and <code>Event.stopImmediatePropagation()</code>?</strong></p>\n<p>Adding <strong>Event.stopPropagation()</strong> to the first function, like so, will print <strong>1, 2</strong> to the console.</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=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">first</span><span class=\"mtk1\">(</span><span class=\"mtk12\">event</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">event</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stopPropagation</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=\"mtk7\">1</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>This is because <strong>Event.stopPropagation()</strong> will immediately prevent all click events on the <em>parent</em> from being triggered, but it does <strong>not</strong> stop any <strong>other</strong> event handlers from being called.</p>\n<p>As you can see in our example, our button has two click handlers, and it <em>did</em> stop the propagation to its parents. If you wanted to stop <em>all</em> event handlers after the first, <em>that’s where</em> <strong>Event.stopImmediatePropagation()</strong> <em>comes in.</em></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">first</span><span class=\"mtk1\">(</span><span class=\"mtk12\">event</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">event</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stopImmediatePropagation</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=\"mtk7\">1</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Now, the first function <em>really will</em> stop the parent click handlers, and all other click handlers. The console will now print just <strong>1</strong>, whereas if we simply used <strong>Event.stopPropagation()</strong>, it would print <strong>1, 2</strong>, and not including either would print <strong>1, 2, 3</strong> .</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n</style>","frontmatter":{"date":"July 22, 2019","updated_date":null,"description":null,"title":"JavaScript Events: Bubbling, Capturing, and Propagation","tags":["JavaScript","JavaScript Events"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.3333333333333333,"src":"/static/ec578c09d831dd93165ad9409178344c/c0886/bubbles.png","srcSet":"/static/ec578c09d831dd93165ad9409178344c/69585/bubbles.png 200w,\n/static/ec578c09d831dd93165ad9409178344c/497c6/bubbles.png 400w,\n/static/ec578c09d831dd93165ad9409178344c/c0886/bubbles.png 772w","sizes":"(max-width: 772px) 100vw, 772px"}}},"author":{"id":"Greg Sakai","github":null,"avatar":null}}}},{"node":{"excerpt":"It is hard to write 100% holes-free code, no matter how hard you try. Sometimes it is not even your own fault (language implementation…","fields":{"slug":"/engineering/3-simple-ways-to-secure-your-websites-applications/"},"html":"<p>It is hard to write 100% holes-free code, no matter how hard you try. Sometimes it is not even your own fault (language implementation, server setups, etc.) and those factors are likely out of your control. That being said, as developers, we should strive to write our code as safe and secure as possible. Here are my suggestions to keep yourself from being woken up in the middle of the night:</p>\n<p>1. <strong>DO NOT trust any user-input, PERIOD.</strong> Not even if it is yours truly. This is the most common attack vector for your web applications, whether it is just a contact form or an API end-point. For example, if a form is implemented to store data in a database, someone can try brute-forcing with classic SQL-injection techniques. Others can certainly try calling your API and see if there are any spotty error-handling issues. Sanitize all inputs as much as you can, and handle all errors behind the scenes properly and gracefully without exposing the actual details to the public.</p>\n<p>2. <strong>UPDATE, UPGRADE and REPEAT.</strong> Chances are, a lot of your code is dependent on third-party libraries (open or closed source, does not matter). It is your job to make sure you are using the latest version for them all. When hackers find out you are using outdated or vulnerable code, you are done. I have seen this happening way too many times than I can count over the years when websites got hacked and outdated plugins or libraries was the main culprit.</p>\n<p>You might be saying, \"Hey, upgrading that library will break my code!!\". Well, what is your job again? Deal with it.</p>\n<p>3. <strong>Web Application Firewall (WAF)</strong> Consider getting one if your server admin lets you, it can potentially save yourself a lot of embarrassments. Just keep in mind though it should not be your only security strategy, as WAFs will not stop all kinds of attacks. It is still your sole responsibility to write good code and repeat step 1 and 2.</p>\n<p><strong>Happyyyyy coding!</strong></p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"June 24, 2019","updated_date":null,"description":null,"title":"3 Simple Ways to Secure Your Websites/Applications","tags":["Engineering"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/a83283c1ebd13e5b72cee8093889ff72/2a4de/hacker.png","srcSet":"/static/a83283c1ebd13e5b72cee8093889ff72/69585/hacker.png 200w,\n/static/a83283c1ebd13e5b72cee8093889ff72/497c6/hacker.png 400w,\n/static/a83283c1ebd13e5b72cee8093889ff72/2a4de/hacker.png 600w","sizes":"(max-width: 600px) 100vw, 600px"}}},"author":{"id":"Karl Wittig","github":null,"avatar":null}}}},{"node":{"excerpt":"Do you remember the Amazon outage that affected several high-profile customers back in 2011? On April 21st, widely-used sites such as Reddit…","fields":{"slug":"/engineering/failover-systems-and-loginradius-99-99-uptime/"},"html":"<p>Do you remember the Amazon outage that affected several high-profile customers back in 2011? On April 21st, widely-used sites such as Reddit and Quora were brought down, and many others experienced latency or were knocked offline, too. Early that morning, as part of normal scaling activities, Amazon staff performed a network change. However, the change was done incorrectly and, after the staff attempted to correct it through a rollback, the inner mechanisms of the service made it unavailable to serve read and write requests. The ‘inner mechanisms’ responsible for the service unavailability are out of the scope of this article, but they are described in the <a href=\"https://aws.amazon.com/message/65648/\">service disruption summary</a> that Amazon published. What interests us here is the strategies that companies can use to mitigate the negative effects on their products when a service they rely on fails. These strategies make up what is known as a <em>failover system</em>.</p>\n<p>A failover system is a set of mechanisms that perform <em>failover</em>. In computer networking, failover is the process of switching to a redundant or standby server or network upon the <strong><em>abnormal</em></strong> termination of a previously-active server or network. The benefit of a failover system is obvious: with one in place, you can ensure your product or service will be available even when adverse events take place. Uptime—time during which a service is operational—is crucial to the success of your business. If your services are unavailable, you are likely to lose customers and any revenue they would have generated. In an article entitled <a href=\"https://medium.com/netflix-techblog/lessons-netflix-learned-from-the-aws-outage-deefe5fd0c04\">‘Lessons Netflix Learned from the AWS Outage</a>,’ Netflix talks about the manual process they used to deal with the Amazon outage and acknowledges the importance of automating this process in the future so they can keep scaling their service. That is, the company acknowledges the importance of having an automated failover system in place instead of relying on a team of top engineers <strong><em>manually</em></strong> making changes every time there is an issue.</p>\n<p>How is an automated failover system set up? Let us consider the simplest scenario: setting a failover system for one server. By definition of a failover system, in addition to the main server, we need to have another redundant standby server that we can switch to whenever the main one fails. Since the redundant server must provide the same functionality as the first, it must be identical to it. Additionally, we need a tool that ensures client requests are routed to the redundant server in case of failure of the main one. We can achieve this by using a DNS failover tool. DNS is the internet protocol used to translate human-readable hostnames into IP addresses, and a DNS failover tool makes sure the “dictionary” (DNS tables) used for this translation are updated in the event of an outage. DNS failover tools know when to update the tables by periodically checking on the main server’s status. With these three tools—and some configuration—you can set up a simple, automated failover system. Of course, there are other considerations you must take when setting the failover system, such as ensuring the redundant standby server is hosted in a geographic area different from the main server’s location and using different companies to host your services. That way, your services will be less likely to go down simultaneously. </p>\n<p>At LoginRadius, we have set up automated failover systems in all layers of our architecture, which is why we can ensure 99.99% uptime on a monthly basis. With our services, you can be assured your customers will always be able to engage with your business, ensuring you will never lose these customers and any revenue they will generate. </p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"June 24, 2019","updated_date":null,"description":null,"title":"Failover Systems and LoginRadius' 99.99% Uptime","tags":["Engineering","AWS"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.0050251256281406,"src":"/static/b25cc95f0b8e5c745ef8652dfb386e3b/40823/tech.jpg","srcSet":"/static/b25cc95f0b8e5c745ef8652dfb386e3b/f836f/tech.jpg 200w,\n/static/b25cc95f0b8e5c745ef8652dfb386e3b/2244e/tech.jpg 400w,\n/static/b25cc95f0b8e5c745ef8652dfb386e3b/40823/tech.jpg 719w","sizes":"(max-width: 719px) 100vw, 719px"}}},"author":{"id":"Ruben Gonzalez","github":"rubenprograms","avatar":null}}}},{"node":{"excerpt":"Bots are tools that are created to automate tedious processes and reduce work. For example, chatbots automate replies to users for customer…","fields":{"slug":"/engineering/a-bot-protection-overview/"},"html":"<p>Bots are tools that are created to automate tedious processes and reduce work. For example, chatbots automate replies to users for customer support, and search bots are used to populate search results on a Google search. However, there are many bots that are crafted for the malicious self-interest of a party. Examples of these hostile bots include DDOS (Direct Denial of Service) botnets and spam bots. This post will provide some information on how to implement bot protection to protect your systems from these nasty bot attacks.</p>\n<h3 id=\"captcha\" style=\"position:relative;\"><a href=\"#captcha\" aria-label=\"captcha permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>CAPTCHA:</h3>\n<p>One of the most popular methods of bot protection that is used today is CAPTCHA, which is provided through companies such as ReCAPTCHA, NuCaptcha and Solve Media. CAPTCHA, which stands for “Completely Automated Public Turing Test to tell Computers and Humans Apart”, is an anti-bot measure which consists of a challenge which a user must complete to verify if the user is human. Examples of challenges include translating images of distorted text, or recognition of objects in an image which match a given word. CAPTCHAs are useful in blocking automated form submissions by bots and are constantly being updated to be more friendly to human users. Some of the latest CAPTCHA implementations only require the user to click on a checkbox to pass their validation check.</p>\n<p>An example of a ReCAPTCHA with distorted text</p>\n<p><img src=\"https://media-s3-us-east-1.ceros.com/editorial-content/images/2018/05/31/c5c224dc0fb2a058625073c470d70c3c/recaptcha-big.png?ver=1552286291?imageOpt=1&#x26;fit=bounds&#x26;width=1077\"></p>\n<p>To implement CAPTCHA using Google’s ReCAPTCHA solution, you can access <a href=\"https://www.google.com/recaptcha/\">Google reCAPTCHA bot protection</a> and login with your Google account. Following that you will be redirected to an interface where you can register your site. Different types of CAPTCHAs can be set up for different events on your domain and can be built to match your use case.</p>\n<p>An example of a ReCAPTCHA with a checkbox validation</p>\n<p><img src=\"https://media.giphy.com/media/10p3VEnw29dD44/giphy.gif?ver=1552286291?ver=1552286291\"></p>\n<p>CAPTCHAs have a variety of uses, and can be used to prevent automated form completions and even prevent access to your domain. Setting up a CAPTCHA detection solution for different scenarios will typically provide a strong bot defense for your system.</p>\n<h3 id=\"spam-honeypots\" style=\"position:relative;\"><a href=\"#spam-honeypots\" aria-label=\"spam honeypots permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Spam Honeypots:</h3>\n<p>Spam honeypots are traps that ensnare bots by placing hidden input fields within a form that reject registration upon being filled in. Bots that use detect form fields through HTML may be programmed to fill in all the input fields in a form including the honeypot. Meanwhile, since the fields are hidden, human users should not be able to see the honeypot and should not be filling in the field.</p>\n<p>The implementation of a honey pot can be as simple as implementing an extra form field onto your page that should not be filled in. Hide the element using CSS and set up logic to prevent users that fill in the field from successfully completing the form. A simple implementation can be done with this code:</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=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;first-name-input&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;text&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;firstname&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Fill me in&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">style</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;display: none;&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;honeypot-input&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;text&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;honeypot&quot;</span><span class=\"mtk17\">&gt;</span><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;button&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">onclick</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;submitForm()&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;button&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Submit</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span><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;button&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">onclick</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;fill()&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;button&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Fill Honeypot</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">    let submitForm = function() </span><span class=\"mtk4\">{</span><span class=\"mtk1\">         </span><span class=\"mtk12\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">honeypot</span><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\">&quot;honeypot-input&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk12\">value</span><span class=\"mtk1\">;         </span><span class=\"mtk11\">if</span><span class=\"mtk1\">(!</span><span class=\"mtk12\">honeypot</span><span class=\"mtk1\">) { </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk3\">// Handle input submit            </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        console.log(“Pass”);         } </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk12\">else</span><span class=\"mtk1\"> { </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk3\">// Handle honeypot error            </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    console.log(“Fail”);  }  </span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     let fill = function() </span><span class=\"mtk4\">{</span><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\">&quot;honeypot-input&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk12\">value</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;Example&quot;</span><span class=\"mtk1\">;     </span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>With the implementation of the above code, if a bot is setup to fill in all input fields on your web page, then the hidden honeypot input will be filled in and the bot will be detected. On the other hand, if a normal user attempts to complete the form on the page, the honeypot would be invisible and the registration will be successful.</p>\n<p>Honeypots are a solution to weed out basic bots, but they can be easily circumvented depending on how the honeypot is implemented. Regardless, adding a honeypot still provides an additional layer of defense against bot inputs and will help deter some bot traffic on your site.</p>\n<h3 id=\"lockout-time\" style=\"position:relative;\"><a href=\"#lockout-time\" aria-label=\"lockout time permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Lockout Time:</h3>\n<p>Often times, when bots are created to automate a task, they would be programmed to complete these tasks as quickly as possible to maximize efficiency. As a countermeasure, time lockouts can be set up to prevent bots from repeatedly spamming requests. By setting up a time lockout between requests to your domain, bots which attempt to quickly submit data on your domain will be detected. Meanwhile, human users that are registering onto the site will be working at a slower pace and will not notice the time lockout at all.</p>\n<p>Setting a timer on form completion does not prevent any bots from affecting your domain, but can significantly slow down their efficiency. Combined with ReCAPTCHA or other anti-bot measures, it can be very useful in reducing the impact of bots.</p>\n<h3 id=\"blacklisting-ips\" style=\"position:relative;\"><a href=\"#blacklisting-ips\" aria-label=\"blacklisting ips permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Blacklisting IPs:</h3>\n<p>If an entity accessing your website is from an unexpected location, for example, a Russian IP accessing your domain for an American service, using IP blacklists may be useful to prevent possible bot attacks. IP blacklisting can usually be set up through your hosting services and allows you to customize where users may access your domain.</p>\n<p>There are some issues with blacklisting, though. Choosing which targets to blacklist could be a tedious task. Even with a bot set up to detect users with suspicious activity and block them, there could be a chance of a false positive, which may result in users of your domain being blacklisted.</p>\n<h3 id=\"proof-of-work\" style=\"position:relative;\"><a href=\"#proof-of-work\" aria-label=\"proof of work permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Proof Of Work:</h3>\n<p>If you want to save your site from spams and denial-of-service attacks you can incorporate a layer of Proof Of Work algorithm in your site. Whenever any client will try to connect to your server they need to commit some of their resources to the Proof Of Work algorithm first and then the server should be connected.</p>\n<p>With this approach, any legitimate user would experience just a negligible computational cost, but a spammer/attacker trying to establish a large number of connections would bear the computational cost and time delay, it deters the abuser to do so. There are many POW algorithms which you can use eg:- <a href=\"https://en.wikipedia.org/wiki/Client_Puzzle_Protocol\">Client Puzzle Protocol</a>, Productive Puzzle Protocol, <a href=\"https://en.wikipedia.org/wiki/Guided_tour_puzzle_protocol\">Guided Tour Puzzle Protocol</a></p>\n<h3 id=\"other-forms-of-malicious-bots\" style=\"position:relative;\"><a href=\"#other-forms-of-malicious-bots\" aria-label=\"other forms of malicious bots permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Other Forms of Malicious Bots:</h3>\n<p>Other malicious bots that can impact user experience negatively include, but are not limited to, bots designed for DDOS attacks, spam bots that harvest user data, bots that create links to phishing websites which generate viruses, and malicious bot worms that infect computers.</p>\n<p>Countermeasures for these bots vary depending on what is being prevented. Honeypot data fields can act as a detection method against bots harvesting data, and with proper preventative training, phishing and scam bots can be handled. Third party services may also be used to protect from different forms of bots. For example, to mitigate impacts of DDOS attacks, a user may implement a solution offered by CloudFlare. Another example is the use of an ad blocker to prevent malware from being drive-by downloaded by intrusive ads.</p>\n<h3 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion:</h3>\n<p>Unless your domain is a highly popular website, or is being targeted by technical security violation experts, there is a good chance that utilizing a simple Google ReCaptcha prompt for form completion is enough to handle any malicious bots that attempt to access your website. For domains with significantly more traffic, paid solutions like Cloudflare might also be useful in dealing with malicious bots.</p>\n<p>Keep in mind that although some bots are created for bad purposes, a large number of bots exist to automate beneficial tasks and make it easier for humans. Even though there are a significant amount of bots that are not helpful, it is important to embrace how useful benevolent bots actually are.</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 .mtk17 { color: #808080; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n</style>","frontmatter":{"date":"May 31, 2019","updated_date":null,"description":null,"title":"A Bot Protection Overview","tags":["Engineering","Captcha","Spam","Secure","IP"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.2578616352201257,"src":"/static/010dd09dba7a6b0a11d58d980e3f0306/14b42/Productshot.jpg","srcSet":"/static/010dd09dba7a6b0a11d58d980e3f0306/f836f/Productshot.jpg 200w,\n/static/010dd09dba7a6b0a11d58d980e3f0306/2244e/Productshot.jpg 400w,\n/static/010dd09dba7a6b0a11d58d980e3f0306/14b42/Productshot.jpg 800w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Chris Yee","github":null,"avatar":null}}}},{"node":{"excerpt":"OAuth2 is an authorization delegation protocol that allows one party’s accessing of an end user’s resources stored with another party…","fields":{"slug":"/engineering/what-is-the-difference-between-oauth1-and-oauth2/"},"html":"<p>OAuth2 is an authorization delegation protocol that allows one party’s accessing of an end user’s resources stored with another party without sharing any credentials. OAuth2 is often compared with SAML and OpenID Connect as their purposes and uses overlap, however these comparisons often refer to OAuth2 as OAuth. This has resulted in some confusion regarding OAuth2 and OAuth1.</p>\n<p><a href=\"https://tools.ietf.org/html/rfc5849\">OAuth1</a> was published in 2010, and <a href=\"https://tools.ietf.org/html/rfc6749\">OAuth2</a> is a complete rewrite of OAuth1 released in 2012. The following section will go over the most significant needs that led to this rewrite, along with the change associated to address them.</p>\n<h3 id=\"support-for-non-browser-based-applications\" style=\"position:relative;\"><a href=\"#support-for-non-browser-based-applications\" aria-label=\"support for non browser based applications permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Support for non-browser based applications</h3>\n<p>One of the commonly agreed-upon disadvantages of OAuth1 was the lack of support it offers to non-browser based application clients. OAuth2 has different authorization work flows to address authorization initiated by native application clients. This was one of the main advantages OAuth2 has over OAuth1. However, abuse of the flows in favour of convenience and ease can lead to insecure implementations of OAuth2. When using OAuth2 for mobile, desktop, or single page applications, it is recommended to refer to the IETF paper going over best OAuth2 practices for mobile apps: <a href=\"https://tools.ietf.org/html/rfc8252\">IETF</a>.</p>\n<h3 id=\"ease-of-implementation\" style=\"position:relative;\"><a href=\"#ease-of-implementation\" aria-label=\"ease of implementation permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Ease of implementation</h3>\n<p>OAuth1 was often criticized for the barrier it poses to writing a client as each exchange between client, server, and resource server requires a validation of a shared secret. This secret is used to sign the arguments for the authorization request by the client, subsequently the server signs the arguments with the client’s key to verify the legitimacy of the client. The arguments need to be passed in the exact order and is often finicky to write. Moreover, dealing with cryptographic signing of the requests in addition to this can be a pain.</p>\n<p>OAuth2 has delegated this part of the security to transfer over HTTPS. This means while OAuth1 is protocol-independent, OAuth2 requests must be sent over SSL. Since TLS already provides transport-level message privacy and integrity, some question the merit of arguably redundant client-side signing and argument sorting. Others have brought up concerns with completely delegating security to HTTPS, and mention reasons such as yet-undiscovered zero-day TLS vulnerabilities potentially compromising entire systems.</p>\n<h3 id=\"clear-separation-of-roles\" style=\"position:relative;\"><a href=\"#clear-separation-of-roles\" aria-label=\"clear separation of roles permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 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 separation of roles</h3>\n<p>The conceptualization of OAuth2 defines a resource server in addition to an authorization server. This means there is a clear separation of roles between the server that handles the authorization request, and the server that makes access-control decisions based on the response to the authorization request. This separation of concerns allows support for more flexible use cases.</p>\n<h2 id=\"so-oauth1-or-oauth2\" style=\"position:relative;\"><a href=\"#so-oauth1-or-oauth2\" aria-label=\"so oauth1 or oauth2 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>So, OAuth1 or OAuth2?</h2>\n<p>All of the above points seem to suggest OAuth2 as a superior alternative to OAuth1, and that OAuth1 is obsolete. This is not the case. It is very rare to see a greenfield authorization system using OAuth1, and the only major player still using OAuth1 is Twitter -- they call their version OAuth1.0a. However, as far as security and usability is concerned, OAuth1 is still viable and perhaps even more secure than OAuth2 since it offers additional security on top of TLS-based precautions, and creates barriers in potentially compromising flows. An existing system that uses OAuth1 probably does not need to upgrade to OAuth2. New systems that rely on server-to-server authorization could probably leverage OAuth1 for the additional security as well. On the other hand, use cases that could benefit from a separation of concerns, non-browser support, and ease of client development should go for OAuth2.</p>\n<p>OAuth2 has received its own share of criticisms. For example, in 2012 Eran Hammer, one of the original authors of OAuth2, withdrew his name from the specification and wrote <a href=\"https://gist.github.com/nckroy/dd2d4dfc86f7d13045ad715377b6a48f\">an article</a> calling out its many flaws. However, even in this article he agreed with the usefulness of OAuth2, and that “at the hand of a developer with deep understanding of web security will likely result in a secure implementation”.</p>\n<p>OAuth2 is not necessarily more secure than OAuth1, and using OAuth2 does not inherently lead to better security. Many considerations must go into each specific implementation. For starters, the appropriate grant flow must be chosen with care pertaining to the use case; the redirect_uri must be validated sufficiently; and measures must be taken to prevent access tokens from ending up in the browser history. For additional security considerations, see this <a href=\"https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-10\">IETF work in progress draft on OAuth Security Best Current Practice</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":"May 31, 2019","updated_date":null,"description":"Learn about the differences between OAuth 1.0 and OAuth 2.0 and how OAuth 2.0 is superior to OAuth 1.0","title":"OAuth 1.0 VS OAuth 2.0","tags":["Oauth","Engineering"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/1c2dae61b8f7fee8ab8408c5d18cd8b4/14b42/pexels-photo-373543.jpg","srcSet":"/static/1c2dae61b8f7fee8ab8408c5d18cd8b4/f836f/pexels-photo-373543.jpg 200w,\n/static/1c2dae61b8f7fee8ab8408c5d18cd8b4/2244e/pexels-photo-373543.jpg 400w,\n/static/1c2dae61b8f7fee8ab8408c5d18cd8b4/14b42/pexels-photo-373543.jpg 800w,\n/static/1c2dae61b8f7fee8ab8408c5d18cd8b4/47498/pexels-photo-373543.jpg 1200w,\n/static/1c2dae61b8f7fee8ab8408c5d18cd8b4/0e329/pexels-photo-373543.jpg 1600w,\n/static/1c2dae61b8f7fee8ab8408c5d18cd8b4/2d44f/pexels-photo-373543.jpg 2250w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Ti Zhang","github":null,"avatar":null}}}},{"node":{"excerpt":"This blog post goes over how you can connect your SAAS/web application with the Azure AD world. Let’s take a look at how Azure AD works as…","fields":{"slug":"/engineering/azure-ad-as-an-identity-provider/"},"html":"<p>This blog post goes over how you can connect your SAAS/web application with the Azure AD world. Let’s take a look at how Azure AD works as an identity provider to provide your users with the ability to log in. e.g if anyone using Office 365, able to log on with their standard account or a federated one.</p>\n<p>Windows Azure provides a number of identity-based technologies to support such kind of requirements. As a means of illustrating this, we’ll show an example using Azure AD as an Identity Provider (IdP), connecting up to the LoginRadius SAAS application using the LoginRadius Admin Console.</p>\n<ul>\n<li>Log in to the Azure Portal.</li>\n<li>On the Azure active directory tab, click on the App registrations tab.  From the top of the screen, create a new application by clicking on \"New application registration\".</li>\n</ul>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 480px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 86.04166666666667%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAAAsTAAALEwEAmpwYAAADAklEQVQ4y22UW0/TcBjG91HYBmOw7ryx4roDJ8EdYCCCRhM1bAE1xksv/DTCDZELrrnjk4wQTTSyrYe1GxuMx/f9z9YSbPKk65L++jzv4e95WW9gtVTG+noV1WoVtVoNlUoFsixjbm4O5+fn4KvVG0LrmlDVDkZ3d7CvO/rNury8xHA4hGepVIEUjSIeiyFGSiQSkCQJXq8XPp8PZ2dn4sUfmgXNtGAYOq6vr4X6/T5ubm4wGo3QbDYxGAzgWX/VgJwrIp9TkM1msbCwIKB+vx9TU1M4Pj4WwGZbh2oYUDsddEhXV1dCvV5POHSA5ZqCcDSIZDKNdDotYNPT05icnBT6engogD9VHW1Nh6HrwpE7Mj9fXFyMIz+u5hCNS1SvjFO3QCDgAI+OjsSL31vkzuii2+0KV+64LP6f75564wUKhSyUrIL5+XkoioJMJoNJjuwCNtsDAlrQNQ3tdlvEZke2Q/6IABYWFYQiEpIUN55MinsoHIaXgD6SDdR6KvSuRjWkO8Vmcc1soGVZY6CcmcMjApWXlrFaLKKyvAI5nkB4KgBpOugAdXLQNU0BsiOzQzuyA/zy7iPqtS28Wd/AXm0TbzdqaDzdxmt6PihXcHpyMgZaY6CqqqJ27obcA35u7Avg3uYW9ref4WBnF+93n6NO0AOa0dNvY+CVGGxLdFmjOnIN2Slf94CfPtRRXVlCiSJnUymEqBERGhuWRLIjW30TpmXSYBuioyyG2LEd4FppDZFYFClqxkwoJBrhp4H2EdjdlLv+L/RMboghoCy7nuKDNrC0ukpDnaTRKWB2dhbeiQmxISz3HJr9WxgUmXeZQVxLjt5qtUSDnLF5spFGJE6bkkghRZF5W2ZmZh4M9nBgkgvTcWhSg9z77ADXajJiiRANs4xkKimg7I4PB7878vA3ukabHHWEO4baJw2LXd/e3tLhsJOCPC/RwZBDkeZwcXER+XxerCA7Pfy7y6N/J9aDo4tlb41HyckIBgOIRCJCUTrKwrQpXE926jh0vWzrf9cfT9jsk9Zcp3IAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"1\"\n        title=\"1\"\n        src=\"/static/20af250efd33089032a385eebeaf2b97/e85cb/1.png\"\n        srcset=\"/static/20af250efd33089032a385eebeaf2b97/e85cb/1.png 480w\"\n        sizes=\"(max-width: 480px) 100vw, 480px\"\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<ul>\n<li>Give your SaaS/Web application a name (company name Demo).  Using the drop-down, select the type of application i.e Web Application / Web API.</li>\n<li>For Sign-On URL fill in the Assertion Consumer Service (ACS) URL for the Service Provider</li>\n</ul>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 532px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 98.49624060150376%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAADAElEQVQ4y52U207iYBSFeQ0PiICcj2KlgICgcOEkc2DexItJJoE5vIFeeuOFMepDTWbujAMILVCgHNfsvbGOGufYZKWltF/X3uvfv01JB1EsFlAqlbC/v49yuYxEIoFIJIJYLAaPx4OtrS3s7OzAsb4Ou30Na2s/tbq6Cq/Xh3wuh1hCgc0f9GJzc1NeisfjCAQCAnE6nQiGQjg8PMTnTx9Rq9VQq1bxgc4PJfdrfL+Kd++rBAyEBZZOpwXscrnoi14BJpNJaK02+NC6BiYz/PaYkGyRkBuhcJjchMUZw3w+H4HdUvKXr9/Q1Pu4abbRaHdxqxuotzr0W8P3Wx1abwjdGNLZxA39tsWiXkSjUYQjUWxsbIgYuE79qlQqaNTr6A/opU4X3Z6BRrMJczTGfA5MZ3PSDJPpwnq72ydg6SUURUGOmlosFiUMdrq8vIzz83N5sE7Q6+trNBoNtNttmOYQo9EII9OksynXw0EfLb1HwGQGMQqD+8hg7mMwGMTS0hIuLi8FaPb7MFiGgU6nI/fmZNHSjFyyZY0dJnN5KNvb2CapqipBhKmnAry4kJd1TUOLnLG7JpXMYFav1xOZ5HQ2naLVIYfZgwpBVEk5m80KkIPhki/vHI7H43tN6UUuka+lbNJkQvnOZ9RDgx3GZCGzOxavRQ5lZWUFJycnUtKfDusRrUclpwq0DpUEMpmMOORyORQGHh0diaOnPXtO98BXr8tIpVQBcih85mnhko+Pjx8Bf+3wATCeiEjCViAM9fv94vC/gE63SyAcCm8AfM3j99/AZOmAeqggpS6S5pL39vbgcDikh7LG/qWHueKuuOJyeUpCtMPwKNrtdnH4EPhXDt++eSH9Y3ecrtvtfpQyrzeGWuIWPNVE2jJfjB67UzkMmhTunbU5cMqnp6fydV68g8EAw+FQAE/LtargLc62nQwjcbfB8gxzwhbw6upqMcs0Wrquy5hZIT13SMn5Aw9SaRX5/C4KhYKArd3m7OxMXPVpY2AoX7PT58T/8Rb3AwJBiS8k3xWZAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"2\"\n        title=\"2\"\n        src=\"/static/0bca64781f2836e8e64d5c3b716adccc/89a37/2.png\"\n        srcset=\"/static/0bca64781f2836e8e64d5c3b716adccc/89a37/2.png 532w\"\n        sizes=\"(max-width: 532px) 100vw, 532px\"\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<ul>\n<li>Go to the App setting at the top of the page and fill in the required fields</li>\n<li>Go to the endpoints at the top of the application registration page and use these app endpoints to set up the azure ad with your saas application.</li>\n</ul>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 493px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 124.13793103448276%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAZCAIAAAC+dZmEAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACDUlEQVQ4y51UiZKqMBD0/39PkGN3ATkTAoRwCAr4XidBV2tZt8pWxwnY03PJ7t9bWJal67odvoQQfd93bScU2raFf71eX/Pxgx0+nFfgDMNQ13VVcXD7rkPQP/V39zCPUnBBnheJedZWn54iyrRZkQOMsSzNYAnNKKUky9I0LcoSvr7LWJ7T/Hw+P5LnKArLqhqGUSZ8Osmau7ZtBCx6gYoa0XRdL1shGly5pymVy7LUZXPOhaibpsERAea/yt6N42g7tus6ruPYtiNxs67rep73qfD1AE9Bki+XC2pLYolM1ilLTZIY30VR1L8A2Uky2hiGoe/7QeDDCY/yFfgezllG+BaqqkIXV3IA+Ct0VgiCXGSoLURRhOxWMjxEgiUki+MkzQgrikFh/AV6YJIMqQ+F7558vgLuo5crGX2SG0IJlgAtwxtLOk2XWWHZwjrnaZqhqYYjZ6OtrYamj/YP4KJlWbf1ZAw1Y1XgVJznlHJel0XBcobeokLoPMpO07QqIzFoGKZh2dbhcLBs2zQN0zwYe2O/N+BB6uMZUMJclPI8J0lCCIHFnmAMURzjf4A1wJLDih84qf1flREG09Nz9rwvfcxfAgWuZIiFz5BLFgQIEW8hVbit5/GYJimuBn6gZMMwAjEglOJBddoC9mclY+732Whob3NOd3w/ht7DO2TMGQ1Dyu+QQcPDCNvyH07xejQWe6IXAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"A 1\"\n        title=\"A 1\"\n        src=\"/static/6da5ac329fe0cd7ccd2c546fb0b7bf96/f88d0/A-1.png\"\n        srcset=\"/static/6da5ac329fe0cd7ccd2c546fb0b7bf96/f88d0/A-1.png 493w\"\n        sizes=\"(max-width: 493px) 100vw, 493px\"\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 are the meanings of the terms, we have used above: </p>\n<p><strong>Sign-On Url</strong>: This is where you want to send users to when accessing the \"application\". </p>\n<p><strong>Reply URL</strong>: It's the Reply URL which is the address to which Azure AD will send the SAML authentication response.</p>\n<p>On the Service Provider side, the metadata from the tenant, Azure Identity Provider needs to be parsed and added to the configuration file. This is done by downloading the Azure IdP metadata file directly, e.g.</p>\n<p><code>https://login.microsoftonline.com/&#x3C;AzureTenantID>/federationmetadata/2007-06/federationmetadata.xml</code></p>\n<p>This is all you need to know to go about creating a new application on the Azure portal and use Azure Ad as an Identity provider for login. With these and a number of services, Azure offers a solid convergence point for brokering connections with your web applications and workspaces.</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 30, 2019","updated_date":null,"description":null,"title":"Azure AD as an Identity provider","tags":["Engineering","Authentication","AzureAD"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/c3f65c00249c3107c5efe318d12ef2f9/bc59e/TN0lxUr0.png","srcSet":"/static/c3f65c00249c3107c5efe318d12ef2f9/69585/TN0lxUr0.png 200w,\n/static/c3f65c00249c3107c5efe318d12ef2f9/497c6/TN0lxUr0.png 400w,\n/static/c3f65c00249c3107c5efe318d12ef2f9/bc59e/TN0lxUr0.png 512w","sizes":"(max-width: 512px) 100vw, 512px"}}},"author":{"id":"Team LoginRadius","github":"LoginRadius","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":228,"currentPage":39,"type":"//engineering//","numPages":52,"pinned":"17fa0d7b-34c8-51c4-b047-df5e2bbaeedb"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}