{"componentChunkName":"component---src-templates-blog-list-template-js","path":"/engineering/18","result":{"data":{"allMarkdownRemark":{"edges":[{"node":{"excerpt":"Web authentication or WebAuthn is a new standard for authentication published by the World Wide Web Consortium and supported by the FIDO…","fields":{"slug":"/engineering/webauthn-authentication-application/"},"html":"<p>Web authentication or WebAuthn is a new standard for authentication published by the World Wide Web Consortium and supported by the <a href=\"https://fidoalliance.org/fido2/fido2-web-authentication-webauthn/\">FIDO alliance</a>. The standard works by providing a way for users to authenticate through a third-party authenticator. These authenticators can be built into the operating system software, like Windows Hello or Android biometrics, or through external authenticators, like a USB authenticator.</p>\n<p>This article will cover a high-level description of how WebAuthn works and two different ways an application can be set up to use the WebAuthn standard to authenticate users. One is through a basic registration flow where the authenticator data is stored upon registration and must be used to log in. The other is a flow where the authenticator can be used as a second-factor authentication method, prompted after a user logs in. For more information on this, resources like the <a href=\"https://www.w3.org/TR/webauthn-2/\"><code>World Wide Web Consortium documentation</code></a> can be useful.</p>\n<h2 id=\"webauthn-introduction\" style=\"position:relative;\"><a href=\"#webauthn-introduction\" aria-label=\"webauthn introduction permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>WebAuthn Introduction</h2>\n<p>The WebAuthn authentication process involves the interaction between three entities: The relying party, which is the server that handles the credentials of the authenticator and verifies it, a web browser that should support the <a href=\"/website-authentication-protocols/\">web authentication protocol</a>, and the authenticator itself.</p>\n<p>The registration process begins when the client generates some sort of identifying information about themselves. Typically, this would be a user name or an email from the user but could be another identifier sent from the client, such as a randomly generated GUID. Using the Web Authentication APIs with JavaScript, the client can request the relying party to register the authenticator credentials.</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: 48.92307692307692%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAACiklEQVQoz2PgK1jBgIz////P+OnrN4Yf374kf/369fbtW7fO3Lh58+Lde/cuv3n16syXb99vH77xJBeojsG2ewcPun4QwQfEIAlegaKV/OJlaziF8xYy6bXvFLvz57/IsRuP9D+8eGL94vo5qU1HzpluePJfRLttpyBD0hxmoHpukD6ofpA5LCAD2XmBWKBwJTuD7xRWBgYGRgaGJQwMVtlyDPbpGqqh+bYRxQ1ObBaBqlrxNVYMNqlaDB6lMnabfzFx5yxiA+mHYg4gZmLgyV/BwJK9lEGveTPDiuM3OTu2nBcCeVstc3K9dvXqn6aN617p1659a9a04Z1584aXSmUrfkrGd6VI5sxnUM+dyYjhZQOgQamLjjKcuPWMYcLOi2r9Oy9b/fjyQS24bt5S2/rV/52b1/0P69/6379r03+npnX/QWJmWRPKLMsXMThULmLmRTewd/tFhsVHbzGsPHmHYfLuywxrzz1mqFi0k4EhoN6FPWlKE0/ypFre5Ekl7NGdVdzxvU1sSVNqmQOrTZmiOhm4MuYyg7zJAzSIF5uBlWtOMYJiz7VvOzeDZAPPnSunGQ4dPCTVc+g+Q/fRpwy79h6UBckzCDVxuvTtYOXOXy4AigxeZAORAQ802YA0Hb3xKOLVx6/L7z14OOfE6bMLb9y+O+fdh48zPn75tvD5qzd2r99/Yrj08BWTYN5qBn6gPv5CIC5YiWogyJb7L98z3nz6luH/nx/qf37/ivn5/VvA8esPay/df17x/+9v/x8/fsR++fxZ6dfPHyDLga5aCXYZPzYXggQevv7AcOfFO6Ar/zD8+PkLqOkfAwNnsSADgwrH3VcfGP7/+8Pw7esXBqDBUANRIwUA9FBqAVFdUwgAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"WebAuthn Flow\"\n        title=\"WebAuthn Flow\"\n        src=\"/static/4e86f815c05935f7d4f29313348d03eb/e5715/webauthn-flow.png\"\n        srcset=\"/static/4e86f815c05935f7d4f29313348d03eb/a6d36/webauthn-flow.png 650w,\n/static/4e86f815c05935f7d4f29313348d03eb/e5715/webauthn-flow.png 768w,\n/static/4e86f815c05935f7d4f29313348d03eb/0f246/webauthn-flow.png 1118w\"\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>After receiving the request from the client, the relying party generates a challenge based on the options provided by the client. The client receives the response and attempts to get the user to verify the authenticator being used. For example, with Windows Hello as the authenticator, the user can enter their PIN. After verifying the authenticator, it signs the challenge-response back with identifying details and returns it to the relying party, which validates the authenticator and registers the user.</p>\n<p>When the registration begins, options are set from the relying party that changes how the flow will work. You can find a list of the options in this document on <a href=\"https://www.w3.org/TR/webauthn/#dictionary-makecredentialoptions\">W3C</a>. Here are some examples of the significant options that one might set for their flows:</p>\n<ul>\n<li><strong>Authenticator Attachment</strong> - The authenticator being used can be set to a platform authenticator or a cross-platform authenticator. Platform authenticators are limited to the usage of a single device to authenticate. Windows Hello and the fingerprint scanner on a smartphone are examples of platform authenticators, as the user is identified through the device being used to authenticate with. Cross-platform authenticators are external devices that can be used with a device to authenticate. Things like USB authenticators are an example of cross-platform authenticators. Depending on the implementation, USB authenticators can also set up multiple platform authenticators to work on their device, but this won't be covered in this blog.</li>\n<li><strong>Resident Key Required Boolean</strong> - By default, this value is set to false, which means that private key and authentication credentials are stored on the relying party server. However, if this option is set to true, the authenticator will store the private key credentials instead. With certain flows, by setting the resident key to required, only the authenticator's ids will be stored on the relying party server. This would allow for authentication systems to validate a user via the authenticator and identify them.</li>\n<li><strong>User Verification</strong> - This field can hold three values: Preferred by default, Discouraged, or Required. User verification is when the user can be identified to be one that is attempting the authentication request. If an authenticator supports user verification, the authenticator must set a flag during validation and sent to the relying party. When the authenticator attempts verification, it can be done through different means, such as password, PIN, or biometrics.</li>\n<li><strong>Attestation</strong> - Attestation certificates have the option to be created through this option. As a result, the certificate will contain details about the hardware being used as an authenticator and ensure that the device used for authentication is trustworthy. If the authentication flow does not require this, you can set it to None to reduce the workload done by the relying party to validate the attestation certificate. By setting the option to Indirect, the relying party allows the attestation certificate to be generated by a third party. This could allow the relying party to receive less private information surrounding the actual authenticator and use only what is needed. Lastly, if set to direct, the authenticator itself must generate the attestation certificate to be verified.</li>\n</ul>\n<p>The authentication or login process is similar to the registration process. Using the <a href=\"/write-a-javascript-library-using-webpack-and-babel/\">JavaScript libraries</a>, the authenticator passes identifying information to the relying party. The relying party returns a challenge, which should be validated by the user, processed by the authenticator, and finally validated by the relying party. User verification is checked from the options, but a majority of the options have been reduced as no credentials are generated or saved on either end.</p>\n<h2 id=\"setting-up-webauthn-for-your-application\" style=\"position:relative;\"><a href=\"#setting-up-webauthn-for-your-application\" aria-label=\"setting up webauthn for your application permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Setting up WebAuthn for your Application</h2>\n<p>When setting up WebAuthn as an authentication method for your application, two considerations are to use the standard as a primary registration and authentication method or as a second-factor authentication method.</p>\n<p>As a primary authentication method, the authenticator identification and credentials are stored by the server at the same time the user account is created.</p>\n<p>To begin, use the Web Authentication API to initiate the flow:</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=\"mtk12\">Let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">publicKeyCredentialCreationOptions</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">user:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> “</span><span class=\"mtk7\">1234</span><span class=\"mtk1\">”,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;example@example.com&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">displayName:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;example&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">authenticatorSelection:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">authenticatorAttachment:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;platform&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">attestation:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;direct&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">credential</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">navigator</span><span class=\"mtk1\">.</span><span class=\"mtk12\">credentials</span><span class=\"mtk1\">.</span><span class=\"mtk11\">create</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">publicKey:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">publicKeyCredentialCreationOptions</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span></code></pre>\n<p>For this section, the creation options are generated by the client. In other scenarios, including this blog's example, the options are generated from the relying party by retrieving them via an API call.</p>\n<p>After the browser triggers this code, the authenticator will be prompted for validation. Since the authenticatorAttachment is set to 'platform', it would use the device's authenticator, like Windows Hello or an Android fingerprint scan.</p>\n<p>The data returned from the creation of the credentials will have a structure like this:</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=\"mtk12\">PublicKeyCredential</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    id: </span><span class=\"mtk8\">&#39;ADSUllKQmbqdGtpu4sjseh4cg2TxSvrbcHDTBsv4NSSX9...&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    rawId: </span><span class=\"mtk10\">ArrayBuffer</span><span class=\"mtk1\">(</span><span class=\"mtk7\">59</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    response: </span><span class=\"mtk12\">AuthenticatorAttestationResponse</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        clientDataJSON: </span><span class=\"mtk10\">ArrayBuffer</span><span class=\"mtk1\">(</span><span class=\"mtk7\">121</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        attestationObject: </span><span class=\"mtk10\">ArrayBuffer</span><span class=\"mtk1\">(</span><span class=\"mtk7\">306</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    type: </span><span class=\"mtk8\">&#39;public-key&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>This object should be passed to the relying party to complete the registration. The relying party verifies that the credentials passed in are correct and stores the identifier and credentials in the data store. In addition to storing the credentials object, any other registration variables should be passed in this step to register on your data store.</p>\n<p>To use this flow as part of a second-factor authentication process, the user account should be created before initiating this process with an already existing authentication method, like a <a href=\"/password-security-best-practices-compliance/\">password system</a>. After the user account is created, running this flow should update the current user in the data store with the credential data. This will allow the second-factor authentication credentials to be configured and triggered after a password login.</p>\n<p>Most programming languages have a library built that supports WebAuthn for a relying party server. For example, Duo has created them for <a href=\"https://github.com/duo-labs/py_webauthn\"><code>Python</code></a> and <a href=\"https://github.com/duo-labs/webauthn\"><code>Go</code></a>. Using one of these libraries during the development of the relying party server will simplify the process. These resources also provide demos on how to implement their libraries to handle the credential data generated by the JavaScript Web Authentication APIs.</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>Although the usage of WebAuthn is not widespread at the moment, the potential to <a href=\"https://www.loginradius.com/blog/identity/2019/10/passwordless-authentication-the-future-of-identity-and-security/\">authenticate a user passwordless</a> or with the extra security of an authenticator allows it to be a strong contender in the future over regular password authentication flows. Hopefully, this blog helps you get started on your authentication apps with WebAuthn.</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 .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n</style>","frontmatter":{"date":"December 09, 2020","updated_date":null,"description":"Web authentication, or WebAuthn in short. A go-to guide for developers to learn more about WebAuthn API, and how to set it up in their services..","title":"WebAuthn: A Guide To Authenticate Your Application","tags":["WebAuthn","FIDO","Authentication"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/07ab3c5a163821d532aedbc23c7a48be/ee604/webauthn-logo.png","srcSet":"/static/07ab3c5a163821d532aedbc23c7a48be/69585/webauthn-logo.png 200w,\n/static/07ab3c5a163821d532aedbc23c7a48be/497c6/webauthn-logo.png 400w,\n/static/07ab3c5a163821d532aedbc23c7a48be/ee604/webauthn-logo.png 800w,\n/static/07ab3c5a163821d532aedbc23c7a48be/f3583/webauthn-logo.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Chris Yee","github":null,"avatar":null}}}},{"node":{"excerpt":"Let's walk through how to build and push Docker images programmatically using Go. To do this, we need to talk to the Docker daemon via the…","fields":{"slug":"/engineering/build-push-docker-images-golang/"},"html":"<p>Let's walk through how to build and push Docker images programmatically using Go. To do this, we need to talk to the Docker daemon via the <a href=\"https://docs.docker.com/engine/api/\">Docker Engine API</a>. This is similar to how the Docker CLI works, but instead of entering commands through a CLI, we'll be writing code with Docker's Go SDK.</p>\n<p>At the time of writing, the official Docker Go SDK <a href=\"https://docs.docker.com/engine/api/sdk/examples/\">docs</a> provide great examples of running basic Docker commands with Go. However, it's missing examples on building and pushing Docker images, so we'll go over those in this blog.</p>\n<p>Before we begin, this blog assumes you have a working knowledge of Docker and Go. We'll go over the following:</p>\n<ul>\n<li>Building an image from local source code</li>\n<li>Pushing an image to a remote registry</li>\n</ul>\n<h2 id=\"environment-setup\" style=\"position:relative;\"><a href=\"#environment-setup\" aria-label=\"environment setup 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>Environment Setup</h2>\n<p>First, we need to set up the environment. Create a project and include the app we want to containerize:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">mkdir docker-go-tutorial && cd docker-go-tutorial && mkdir node-hello</span></code></pre>\n<p>We'll add a simple Node.js app:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">// node-hello/app.js</span>\n<span class=\"grvsc-line\">console.log(&quot;Hello From LoginRadius&quot;);</span></code></pre>\n<p>with the Dockerfile:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">// node-hello/Dockerfile</span>\n<span class=\"grvsc-line\">FROM node:12</span>\n<span class=\"grvsc-line\">WORKDIR /src</span>\n<span class=\"grvsc-line\">COPY . .</span>\n<span class=\"grvsc-line\">CMD [ &quot;node&quot;, &quot;app.js&quot; ]</span></code></pre>\n<p>Next, install the <a href=\"https://docs.docker.com/engine/api/sdk/\">Go SDK</a>. These are the Docker related imports we will be using:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&quot;github.com/docker/docker/api/types&quot;</span>\n<span class=\"grvsc-line\">&quot;github.com/docker/docker/client&quot;</span>\n<span class=\"grvsc-line\">&quot;github.com/docker/docker/pkg/archive&quot;</span></code></pre>\n<h2 id=\"build-docker-image\" style=\"position:relative;\"><a href=\"#build-docker-image\" aria-label=\"build docker image 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>Build Docker Image</h2>\n<p>One way to build a Docker image from our local files is to compress those files into a tar archive first.</p>\n<p>We use the archive package provided by Docker:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&quot;github.com/docker/docker/pkg/archive&quot;</span></code></pre>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">tar, err := archive.TarWithOptions(&quot;node-hello/&quot;, &archive.TarOptions{})</span>\n<span class=\"grvsc-line\">if err != nil {</span>\n<span class=\"grvsc-line\">    return err</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<p>Now, we can call the ImageBuild function using the Go SDK:</p>\n<ul>\n<li>\n<p>Note that the image tag includes our Docker registry user ID, so we can push this image to our registry later.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">opts := types.ImageBuildOptions{</span>\n<span class=\"grvsc-line\">Dockerfile:  &quot;Dockerfile&quot;,</span>\n<span class=\"grvsc-line\">Tags:        []string{dockerRegistryUserID + &quot;/node-hello&quot;},</span>\n<span class=\"grvsc-line\">Remove:      true,</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\">res, err := dockerClient.ImageBuild(ctx, tar, opts)</span>\n<span class=\"grvsc-line\">if err != nil {</span>\n<span class=\"grvsc-line\">return err</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n</li>\n</ul>\n<p>To print the response, we use a scanner to go through line by line:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">scanner := bufio.NewScanner(res.Body)</span>\n<span class=\"grvsc-line\">for scanner.Scan() {</span>\n<span class=\"grvsc-line\">    lastLine = scanner.Text()</span>\n<span class=\"grvsc-line\">    fmt.Println(scanner.Text())</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<p>This prints the following:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">{&quot;stream&quot;:&quot;Step 1/4 : FROM node:12&quot;}</span>\n<span class=\"grvsc-line\">{&quot;stream&quot;:&quot;\\n&quot;}</span>\n<span class=\"grvsc-line\">{&quot;stream&quot;:&quot; ---\\u003e e4f1e16b3633\\n&quot;}</span>\n<span class=\"grvsc-line\">{&quot;stream&quot;:&quot;Step 2/4 : WORKDIR /src&quot;}</span>\n<span class=\"grvsc-line\">{&quot;stream&quot;:&quot;\\n&quot;}</span>\n<span class=\"grvsc-line\">{&quot;stream&quot;:&quot; ---\\u003e Using cache\\n&quot;}</span>\n<span class=\"grvsc-line\">{&quot;stream&quot;:&quot; ---\\u003e b298b8519669\\n&quot;}</span>\n<span class=\"grvsc-line\">{&quot;stream&quot;:&quot;Step 3/4 : COPY . .&quot;}</span>\n<span class=\"grvsc-line\">{&quot;stream&quot;:&quot;\\n&quot;}</span>\n<span class=\"grvsc-line\">{&quot;stream&quot;:&quot; ---\\u003e Using cache\\n&quot;}</span>\n<span class=\"grvsc-line\">{&quot;stream&quot;:&quot; ---\\u003e 1ff6a87e79d9\\n&quot;}</span>\n<span class=\"grvsc-line\">{&quot;stream&quot;:&quot;Step 4/4 : CMD [ \\&quot;node\\&quot;, \\&quot;app.js\\&quot; ]&quot;}</span>\n<span class=\"grvsc-line\">{&quot;stream&quot;:&quot;\\n&quot;}</span>\n<span class=\"grvsc-line\">{&quot;stream&quot;:&quot; ---\\u003e Using cache\\n&quot;}</span>\n<span class=\"grvsc-line\">{&quot;stream&quot;:&quot; ---\\u003e 6ca44f72b68d\\n&quot;}</span>\n<span class=\"grvsc-line\">{&quot;aux&quot;:{&quot;ID&quot;:&quot;sha256:238a923459uf28h80103eb089804a2ff2c1f68f8c&quot;}}</span>\n<span class=\"grvsc-line\">{&quot;stream&quot;:&quot;Successfully built 6ca44f72b68d\\n&quot;}</span>\n<span class=\"grvsc-line\">{&quot;stream&quot;:&quot;Successfully tagged lrblake/node-hello:latest\\n&quot;}</span></code></pre>\n<p>The last step would be checking the response for errors, so if something went wrong during the build, we could handle it.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">errLine := &ErrorLine{}</span>\n<span class=\"grvsc-line\">json.Unmarshal([]byte(lastLine), errLine)</span>\n<span class=\"grvsc-line\">if errLine.Error != &quot;&quot; {</span>\n<span class=\"grvsc-line\">    return errors.New(errLine.Error)</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<p>For example, the following error can occur during build:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">{&quot;errorDetail&quot;:{&quot;message&quot;:&quot;COPY failed: stat /var/lib/docker/tmp/docker-builder887191115/z: no such file or directory&quot;},&quot;error&quot;:&quot;COPY failed: stat /var/lib/docker/tmp/docker-builder887191115/z: no such file or directory&quot;}</span></code></pre>\n<p>All together, the file looks like this:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">package</span><span class=\"mtk1\"> main</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk8\">&quot;bufio&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk8\">&quot;context&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk8\">&quot;encoding/json&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk8\">&quot;errors&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk8\">&quot;fmt&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk8\">&quot;io&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk8\">&quot;time&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk8\">&quot;github.com/docker/docker/api/types&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk8\">&quot;github.com/docker/docker/client&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk8\">&quot;github.com/docker/docker/pkg/archive&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">dockerRegistryUserID</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">type</span><span class=\"mtk1\"> </span><span class=\"mtk10\">ErrorLine</span><span class=\"mtk1\"> </span><span class=\"mtk4\">struct</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\tError       </span><span class=\"mtk10\">string</span><span class=\"mtk1\">      </span><span class=\"mtk8\">`json:&quot;error&quot;`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\tErrorDetail ErrorDetail </span><span class=\"mtk8\">`json:&quot;errorDetail&quot;`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">type</span><span class=\"mtk1\"> </span><span class=\"mtk10\">ErrorDetail</span><span class=\"mtk1\"> </span><span class=\"mtk4\">struct</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\tMessage </span><span class=\"mtk10\">string</span><span class=\"mtk1\"> </span><span class=\"mtk8\">`json:&quot;message&quot;`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">func</span><span class=\"mtk1\"> </span><span class=\"mtk11\">main</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk12\">cli</span><span class=\"mtk1\">, </span><span class=\"mtk12\">err</span><span class=\"mtk1\"> := client.</span><span class=\"mtk11\">NewClientWithOpts</span><span class=\"mtk1\">(client.FromEnv, client.</span><span class=\"mtk11\">WithAPIVersionNegotiation</span><span class=\"mtk1\">())</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> err != </span><span class=\"mtk4\">nil</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\tfmt.</span><span class=\"mtk11\">Println</span><span class=\"mtk1\">(err.</span><span class=\"mtk11\">Error</span><span class=\"mtk1\">())</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk15\">return</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk12\">err</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">imageBuild</span><span class=\"mtk1\">(cli)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> err != </span><span class=\"mtk4\">nil</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\tfmt.</span><span class=\"mtk11\">Println</span><span class=\"mtk1\">(err.</span><span class=\"mtk11\">Error</span><span class=\"mtk1\">())</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk15\">return</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">func</span><span class=\"mtk1\"> </span><span class=\"mtk11\">imageBuild</span><span class=\"mtk1\">(dockerClient *client.Client) </span><span class=\"mtk10\">error</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk12\">ctx</span><span class=\"mtk1\">, </span><span class=\"mtk12\">cancel</span><span class=\"mtk1\"> := context.</span><span class=\"mtk11\">WithTimeout</span><span class=\"mtk1\">(context.</span><span class=\"mtk11\">Background</span><span class=\"mtk1\">(), time.Second*</span><span class=\"mtk7\">120</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">defer</span><span class=\"mtk1\"> </span><span class=\"mtk11\">cancel</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk12\">tar</span><span class=\"mtk1\">, </span><span class=\"mtk12\">err</span><span class=\"mtk1\"> := archive.</span><span class=\"mtk11\">TarWithOptions</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;node-hello/&quot;</span><span class=\"mtk1\">, &archive.TarOptions{})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> err != </span><span class=\"mtk4\">nil</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk15\">return</span><span class=\"mtk1\"> err</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk12\">opts</span><span class=\"mtk1\"> := types.ImageBuildOptions{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\tDockerfile: </span><span class=\"mtk8\">&quot;Dockerfile&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\tTags:       []</span><span class=\"mtk10\">string</span><span class=\"mtk1\">{dockerRegistryUserID + </span><span class=\"mtk8\">&quot;/node-hello&quot;</span><span class=\"mtk1\">},</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\tRemove:     </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk12\">res</span><span class=\"mtk1\">, </span><span class=\"mtk12\">err</span><span class=\"mtk1\"> := dockerClient.</span><span class=\"mtk11\">ImageBuild</span><span class=\"mtk1\">(ctx, tar, opts)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> err != </span><span class=\"mtk4\">nil</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk15\">return</span><span class=\"mtk1\"> err</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">defer</span><span class=\"mtk1\"> res.Body.</span><span class=\"mtk11\">Close</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk12\">err</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">print</span><span class=\"mtk1\">(res.Body)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> err != </span><span class=\"mtk4\">nil</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk15\">return</span><span class=\"mtk1\"> err</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">nil</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">func</span><span class=\"mtk1\"> </span><span class=\"mtk11\">print</span><span class=\"mtk1\">(rd io.Reader) </span><span class=\"mtk10\">error</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lastLine</span><span class=\"mtk1\"> </span><span class=\"mtk10\">string</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk12\">scanner</span><span class=\"mtk1\"> := bufio.</span><span class=\"mtk11\">NewScanner</span><span class=\"mtk1\">(rd)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">for</span><span class=\"mtk1\"> scanner.</span><span class=\"mtk11\">Scan</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk12\">lastLine</span><span class=\"mtk1\"> = scanner.</span><span class=\"mtk11\">Text</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\tfmt.</span><span class=\"mtk11\">Println</span><span class=\"mtk1\">(scanner.</span><span class=\"mtk11\">Text</span><span class=\"mtk1\">())</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk12\">errLine</span><span class=\"mtk1\"> := &ErrorLine{}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\tjson.</span><span class=\"mtk11\">Unmarshal</span><span class=\"mtk1\">([]</span><span class=\"mtk11\">byte</span><span class=\"mtk1\">(lastLine), errLine)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> errLine.Error != </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk15\">return</span><span class=\"mtk1\"> errors.</span><span class=\"mtk11\">New</span><span class=\"mtk1\">(errLine.Error)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk12\">err</span><span class=\"mtk1\"> := scanner.</span><span class=\"mtk11\">Err</span><span class=\"mtk1\">(); err != </span><span class=\"mtk4\">nil</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk15\">return</span><span class=\"mtk1\"> err</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">nil</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The equivalent Docker CLI command would be:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"12\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">docker build -t &lt;dockerRegistryUserID&gt;/node-hello .</span></code></pre>\n<h2 id=\"push-docker-image\" style=\"position:relative;\"><a href=\"#push-docker-image\" aria-label=\"push docker image 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>Push Docker Image</h2>\n<p>We'll push the Docker image we created to Docker Hub. But, we need to authenticate with Docker Hub by providing credentials encoded in base64.</p>\n<ul>\n<li>In practice, don't hardcode your credentials in your source code.</li>\n<li>\n<p>If you don't want to use your Docker Hub password, you can set up an access token and provide that in the Password field instead.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"13\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">var authConfig = types.AuthConfig{</span>\n<span class=\"grvsc-line\">Username:      &quot;Your Docker Hub Username&quot;,</span>\n<span class=\"grvsc-line\">Password:      &quot;Your Docker Hub Password or Access Token&quot;,</span>\n<span class=\"grvsc-line\">ServerAddress: &quot;https://index.docker.io/v1/&quot;,</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\">authConfigBytes, _ := json.Marshal(authConfig)</span>\n<span class=\"grvsc-line\">authConfigEncoded := base64.URLEncoding.EncodeToString(authConfigBytes)</span></code></pre>\n</li>\n</ul>\n<p>Now, call the ImagePush function in the Go SDK, along with your encoded credentials:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"14\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">opts := types.ImagePushOptions{RegistryAuth: authConfigEncoded}</span>\n<span class=\"grvsc-line\">rd, err := dockerClient.ImagePush(ctx, dockerRegistryUserID + &quot;/node-hello&quot;, opts)</span></code></pre>\n<p>Together, this looks like:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"15\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">func imagePush(dockerClient *client.Client) error {</span>\n<span class=\"grvsc-line\">\tctx, cancel := context.WithTimeout(context.Background(), time.Second*120)</span>\n<span class=\"grvsc-line\">\tdefer cancel()</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">\tauthConfigBytes, _ := json.Marshal(authConfig)</span>\n<span class=\"grvsc-line\">\tauthConfigEncoded := base64.URLEncoding.EncodeToString(authConfigBytes)</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">\ttag := dockerRegistryUserID + &quot;/node-hello&quot;</span>\n<span class=\"grvsc-line\">\topts := types.ImagePushOptions{RegistryAuth: authConfigEncoded}</span>\n<span class=\"grvsc-line\">\trd, err := dockerClient.ImagePush(ctx, tag, opts)</span>\n<span class=\"grvsc-line\">\tif err != nil {</span>\n<span class=\"grvsc-line\">\t\treturn err</span>\n<span class=\"grvsc-line\">\t}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">\tdefer rd.Close()</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">\terr = print(rd)</span>\n<span class=\"grvsc-line\">\tif err != nil {</span>\n<span class=\"grvsc-line\">\t\treturn err</span>\n<span class=\"grvsc-line\">\t}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">\treturn nil</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<p>The equivalent Docker CLI command (after docker login) would be:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"16\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">docker push &lt;dockerRegistryUserID&gt;/node-hello</span></code></pre>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n</style>","frontmatter":{"date":"December 08, 2020","updated_date":null,"description":"Guide on how to build and push Docker images programmatically using Go.","title":"Build and Push Docker Images with Go","tags":["Docker","Go"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.680672268907563,"src":"/static/f7f513d2d6c5460c9f71278fcb98f766/ee604/cover.png","srcSet":"/static/f7f513d2d6c5460c9f71278fcb98f766/69585/cover.png 200w,\n/static/f7f513d2d6c5460c9f71278fcb98f766/497c6/cover.png 400w,\n/static/f7f513d2d6c5460c9f71278fcb98f766/ee604/cover.png 800w,\n/static/f7f513d2d6c5460c9f71278fcb98f766/31987/cover.png 1000w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Andy Yeung","github":null,"avatar":null}}}},{"node":{"excerpt":"What is Istio? Istio is an Open Source service mesh (developed in partnership between teams from Google, IBM, and Lyft), providing a…","fields":{"slug":"/engineering/istio-service-mesh/"},"html":"<h2 id=\"what-is-istio\" style=\"position:relative;\"><a href=\"#what-is-istio\" aria-label=\"what is istio 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 Istio?</h2>\n<p>Istio is an Open Source service mesh (developed in partnership between teams from Google, IBM, and Lyft), providing a dedicated infrastructure layer for creating service-to-service communication that is safe, fast, and reliable. Having such a fanatical communication layer can provide various advantages, like providing observability into communications, providing secure connections, or automating retries and backoff for failed requests.</p>\n<p>A service mesh also often has more complex operational requirements, like A/B testing, canary rollouts, rate limiting, access control, and end-to-end authentication.</p>\n<p>Istio does this by adding a sidecar proxy which intercepts all network communication between microservices, then configures and manages Istio using its control plane functionality, which incorporates:</p>\n<ol>\n<li>Granular control over the service-to-service communication and its routing with the additional functionality of retries, fault injection, circuit breakers.</li>\n<li>Providing secure mTLS without any changes in the application code.</li>\n<li>Cluster to cluster communication using ingress and egress gateways.</li>\n</ol>\n<h2 id=\"istio-architecture\" style=\"position:relative;\"><a href=\"#istio-architecture\" aria-label=\"istio architecture permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Istio Architecture</h2>\n<p>An Istio service mesh is logically split into a data plane and a control plane.</p>\n<p>The data plane is composed of Envoy proxy deployed as sidecars. Envoy itself is an L7 proxy and communication bus designed for modern microservices-based architecture. These proxies intercept and control all network communication between microservices. They also collect and report telemetry on all mesh traffic.</p>\n<p>The control plane manages and configures the proxies to route traffic.</p>\n<p><img src=\"https://istio.io/latest/docs/ops/deployment/architecture/arch.svg\" alt=\"Istio Architecture\"></p>\n<h2 id=\"istio-core-components\" style=\"position:relative;\"><a href=\"#istio-core-components\" aria-label=\"istio core components 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>Istio Core Components</h2>\n<h3 id=\"pilot\" style=\"position:relative;\"><a href=\"#pilot\" aria-label=\"pilot 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>Pilot</h3>\n<p>Istio Pilot manages and configures all the Envoy proxy instances deployed. It takes the rules for traffic behavior provided by the control plane and converts them into configurations applied by Envoy.</p>\n<h3 id=\"citadel\" style=\"position:relative;\"><a href=\"#citadel\" aria-label=\"citadel 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>Citadel</h3>\n<p>Responsible for controlling the authentication and identity management between services. Allow developers to build a zero-trust network based on service identity.</p>\n<h3 id=\"mixer\" style=\"position:relative;\"><a href=\"#mixer\" aria-label=\"mixer 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>Mixer</h3>\n<p>Responsible for enforcing access control and usage policies across the service mesh and collects telemetry data from the Envoy proxy and other services.</p>\n<h2 id=\"istio-features\" style=\"position:relative;\"><a href=\"#istio-features\" aria-label=\"istio features permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Istio Features</h2>\n<h3 id=\"traffic-management\" style=\"position:relative;\"><a href=\"#traffic-management\" aria-label=\"traffic management 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>Traffic Management</h3>\n<p>It is the basic feature of Istio, which facilitates the routing between services. Istio simplifies the configuration of service-level properties like circuit breakers, timeouts, and retries.\nAll traffic that your mesh services send and receive (data plane traffic) is proxied through Envoy, making it easy to direct and control traffic around your mesh without making any changes to your services.</p>\n<p>For discovering all the services in the ecosystem, Istio connects to the Service discovery System and populates its service registry. The Envoy sidecar proxy then uses this registry to route traffic to the correct service.</p>\n<p>Here are a few resources you can add for your deployment apart from the basic service discovery and load balancing:</p>\n<h3 id=\"virtual-services\" style=\"position:relative;\"><a href=\"#virtual-services\" aria-label=\"virtual services 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>Virtual Services</h3>\n<p>Virtual services play a key role in making Istio's traffic management flexible and powerful. They do this by strongly decoupling where clients send their requests from the destination workloads that actually implement them.<br>\nSo, instead of sending requests directly to a service data plane, you send traffic through this virtual service. Using virtual service, you can route requests to different versions of the same service or different hostnames based on particular endpoints. This helps us to do various other things like A/B testing or doing canary rollouts.  </p>\n<p>A typical example:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"yaml\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">apiVersion</span><span class=\"mtk1\">: </span><span class=\"mtk8\">networking.istio.io/v1alpha3</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">kind</span><span class=\"mtk1\">: </span><span class=\"mtk8\">VirtualService</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">metadata</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">name</span><span class=\"mtk1\">: </span><span class=\"mtk8\">bookinfo</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">spec</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">hosts</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    - </span><span class=\"mtk8\">bookinfo.com</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">http</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  - </span><span class=\"mtk4\">match</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    - </span><span class=\"mtk4\">uri</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">prefix</span><span class=\"mtk1\">: </span><span class=\"mtk8\">/reviews</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">route</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    - </span><span class=\"mtk4\">destination</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">host</span><span class=\"mtk1\">: </span><span class=\"mtk8\">reviews  &lt;-- Resolves to reviews.&lt;namespace&gt;.svc.cluster.local</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  - </span><span class=\"mtk4\">match</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    - </span><span class=\"mtk4\">uri</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">prefix</span><span class=\"mtk1\">: </span><span class=\"mtk8\">/ratings</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">route</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    - </span><span class=\"mtk4\">destination</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">host</span><span class=\"mtk1\">: </span><span class=\"mtk8\">ratings</span></span></code></pre>\n<h3 id=\"destination-rule\" style=\"position:relative;\"><a href=\"#destination-rule\" aria-label=\"destination rule 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>Destination Rule</h3>\n<p>We use destination rules to configure what happens to traffic for that destination. Destination rules are applied after virtual service routing rules are evaluated, so they apply to the traffic's real destination.<br>\nUsing destination rules, we specify the subsets of the service using labels, which are then used by the virtual service to route requests to a particular subset. In addition to that, we can also customize traffic policy, load balancing policy, connection pool settings, mTLS, etc.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"yaml\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">apiVersion</span><span class=\"mtk1\">: </span><span class=\"mtk8\">networking.istio.io/v1alpha3</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">kind</span><span class=\"mtk1\">: </span><span class=\"mtk8\">DestinationRule</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">metadata</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">name</span><span class=\"mtk1\">: </span><span class=\"mtk8\">my-destination-rule</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">spec</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">host</span><span class=\"mtk1\">: </span><span class=\"mtk8\">my-svc</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">trafficPolicy</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">loadBalancer</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">simple</span><span class=\"mtk1\">: </span><span class=\"mtk8\">RANDOM</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">subsets</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk3\">#### This will work only if we have defined version label in the deployment</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  - </span><span class=\"mtk4\">name</span><span class=\"mtk1\">: </span><span class=\"mtk8\">v1</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">labels</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">version</span><span class=\"mtk1\">: </span><span class=\"mtk8\">v1</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  - </span><span class=\"mtk4\">name</span><span class=\"mtk1\">: </span><span class=\"mtk8\">v2</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">labels</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">version</span><span class=\"mtk1\">: </span><span class=\"mtk8\">v2</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">trafficPolicy</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">loadBalancer</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">simple</span><span class=\"mtk1\">: </span><span class=\"mtk8\">ROUND_ROBIN</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  - </span><span class=\"mtk4\">name</span><span class=\"mtk1\">: </span><span class=\"mtk8\">v3</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">labels</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">version</span><span class=\"mtk1\">: </span><span class=\"mtk8\">v3</span></span></code></pre>\n<p>Here we have defined destination rule for service <strong>my-svc</strong> and defined subsets and traffic policy global and per subset.</p>\n<h3 id=\"gateway\" style=\"position:relative;\"><a href=\"#gateway\" aria-label=\"gateway 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>Gateway</h3>\n<p>It is used to manage inbound and outbound traffic for your mesh, letting you specify which traffic you want to enter or leave the mesh. Gateway configurations are applied to standalone Envoy proxies running at the edge of the mesh, rather than sidecar Envoy proxies running alongside your service workloads. Using this, we can expose our services to the internet.  </p>\n<p>A typical example would be:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"yaml\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">apiVersion</span><span class=\"mtk1\">: </span><span class=\"mtk8\">networking.istio.io/v1alpha3</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">kind</span><span class=\"mtk1\">: </span><span class=\"mtk8\">Gateway</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">metadata</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">name</span><span class=\"mtk1\">: </span><span class=\"mtk8\">my-svc-gateway</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">namespace</span><span class=\"mtk1\">: </span><span class=\"mtk8\">test</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">spec</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">selector</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">istio</span><span class=\"mtk1\">: </span><span class=\"mtk8\">ingressgateway</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">servers</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  - </span><span class=\"mtk4\">port</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">number</span><span class=\"mtk1\">: </span><span class=\"mtk7\">80</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">name</span><span class=\"mtk1\">: </span><span class=\"mtk8\">http</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">protocol</span><span class=\"mtk1\">: </span><span class=\"mtk8\">HTTP</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">hosts</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    - </span><span class=\"mtk8\">my-svc.example.com</span></span></code></pre>\n<p><strong>istio: ingressgateway</strong> is the gateway which is enabled by default after installation. We can create our custom gateway. Here, the hosts <strong>my-svc.example.com</strong> will resolve to the load balancer provided by the Istio by default. To use this gateway, one has to add config in the virtual service like for example:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"yaml\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">apiVersion</span><span class=\"mtk1\">: </span><span class=\"mtk8\">networking.istio.io/v1alpha3</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">kind</span><span class=\"mtk1\">: </span><span class=\"mtk8\">VirtualService</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">metadata</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">name</span><span class=\"mtk1\">: </span><span class=\"mtk8\">my-svc</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">spec</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">hosts</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  - </span><span class=\"mtk8\">my-svc</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  - </span><span class=\"mtk8\">my-svc.example.com   &lt;-- The host should match</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">gateways</span><span class=\"mtk1\">:               </span><span class=\"mtk8\">&lt;--- gateway config</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    - </span><span class=\"mtk8\">my-svc-gateway</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">http</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  - </span><span class=\"mtk4\">route</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    - </span><span class=\"mtk4\">destination</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">host</span><span class=\"mtk1\">: </span><span class=\"mtk8\">my-svc.test.svc.cluster.local</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">port</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk4\">number</span><span class=\"mtk1\">: </span><span class=\"mtk7\">80</span><span class=\"mtk1\"> </span></span></code></pre>\n<h3 id=\"network-resilience\" style=\"position:relative;\"><a href=\"#network-resilience\" aria-label=\"network resilience 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>Network Resilience</h3>\n<p>This feature provides network configuration dynamically at runtime, which includes retries, fault injection, circuit breakers, and timeouts.</p>\n<h3 id=\"service-entries\" style=\"position:relative;\"><a href=\"#service-entries\" aria-label=\"service entries 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>Service Entries</h3>\n<p>This object is used to add an external service as part of the service mesh, including a service running in a VM or other K8s cluster in case of multi-cluster installation.</p>\n<p>A typical example would be connecting a service to a database cluster that is not part of the mesh.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"yaml\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">apiVersion</span><span class=\"mtk1\">: </span><span class=\"mtk8\">networking.istio.io/v1alpha3</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">kind</span><span class=\"mtk1\">: </span><span class=\"mtk8\">ServiceEntry</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">metadata</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">name</span><span class=\"mtk1\">: </span><span class=\"mtk8\">elasticsearch</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">namespace</span><span class=\"mtk1\">: </span><span class=\"mtk8\">test</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">spec</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">hosts</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  - </span><span class=\"mtk8\">elasticsearch.elasticsearch.svc.cluster.local</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">location</span><span class=\"mtk1\">: </span><span class=\"mtk8\">MESH_INTERNAL</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">ports</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  - </span><span class=\"mtk4\">name</span><span class=\"mtk1\">: </span><span class=\"mtk8\">https</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">number</span><span class=\"mtk1\">: </span><span class=\"mtk7\">9200</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">protocol</span><span class=\"mtk1\">: </span><span class=\"mtk8\">TCP</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">resolution</span><span class=\"mtk1\">: </span><span class=\"mtk8\">DNS</span></span></code></pre>\n<p>The Service Entry should be in the same namespace as that of the calling service. This is helpful, especially in the case where the service is not exposed to a public endpoint and can be accessed using internal service DNS like the above example.</p>\n<h3 id=\"security\" style=\"position:relative;\"><a href=\"#security\" aria-label=\"security 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>Security</h3>\n<p>Istio provides security features that will help us to establish a zero-trust network. Istio enables security by default and provides various authentication and authorization policy to regulate security.</p>\n<p>For example:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"yaml\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">apiVersion</span><span class=\"mtk1\">: </span><span class=\"mtk8\">security.istio.io/v1beta1</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">kind</span><span class=\"mtk1\">: </span><span class=\"mtk8\">PeerAuthentication</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">metadata</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">name</span><span class=\"mtk1\">: </span><span class=\"mtk8\">dsl-es</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">namespace</span><span class=\"mtk1\">: </span><span class=\"mtk8\">pdp-test</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">spec</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">selector</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">matchLabels</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">app</span><span class=\"mtk1\">: </span><span class=\"mtk8\">dsl-es</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">mtls</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">mode</span><span class=\"mtk1\">: </span><span class=\"mtk8\">STRICT</span></span></code></pre>\n<p>Here we define a peer authentication object for a service labeled <strong>my-svc</strong>, which tells that any service that needs to talk to <strong>my-svc</strong> will communicate using mtls. The service will accept only TLS connection. By default, Istio enables <strong>PERMISSIVE</strong> mode, which accepts both plaintext and encrypted communication. </p>\n<p>We can define peer authentication on the mesh, namespace, and pod level.</p>\n<p>That is all for the introduction to Istio. In the next part, we will look at installing Istio and configuring services to use Istio.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n</style>","frontmatter":{"date":"December 07, 2020","updated_date":null,"description":"This post will give a high-level introduction to Istio and its related concepts and terminologies.","title":"Istio Service Mesh: A Beginners Guide","tags":["Istio","Service Mesh"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/452f4d9f7cb358e3d6224ed3aba3d5d6/ee604/Istio.png","srcSet":"/static/452f4d9f7cb358e3d6224ed3aba3d5d6/69585/Istio.png 200w,\n/static/452f4d9f7cb358e3d6224ed3aba3d5d6/497c6/Istio.png 400w,\n/static/452f4d9f7cb358e3d6224ed3aba3d5d6/ee604/Istio.png 800w,\n/static/452f4d9f7cb358e3d6224ed3aba3d5d6/db955/Istio.png 900w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Piyush Kumar","github":"kpiyush17","avatar":null}}}},{"node":{"excerpt":"It is fine when you and the rest of your team are working on different files. But sometimes, multiple people simultaneously work on the same…","fields":{"slug":"/engineering/git-pull-force/"},"html":"<p>It is fine when you and the rest of your team are working on different files. But sometimes, multiple people simultaneously work on the same files, and that's where the problems arise.</p>\n<p>Just a Note: <code>git pull = git fetch + git merge</code></p>\n<p>In this scenario, when you have local changes in your system and you pull the latest contribution, you got this error.</p>\n<p><code>error: your local changes to the following files would be overwritten by merge: readme.md</code>\n<code>please commit your changes or stash them before you merge.</code>\n<code>Aborting...</code></p>\n<h2 id=\"now-you-have-2-major-choices\" style=\"position:relative;\"><a href=\"#now-you-have-2-major-choices\" aria-label=\"now you have 2 major choices 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>Now you have 2 major choices</h2>\n<h3 id=\"choice-1-you-want-to-keep-local-changes\" style=\"position:relative;\"><a href=\"#choice-1-you-want-to-keep-local-changes\" aria-label=\"choice 1 you want to keep local changes 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>Choice 1: you want to keep local changes</h3>\n<p><code>git stash</code>  (stash the local changes clean the workspace)\n<code>git pull</code> (pull the latest changes from remote )\n<code>git stash apply</code> (apply the latest stash)</p>\n<p>-----------(or)---------------</p>\n<p><code>git fetch</code> (fetch the local machine folder)\n<code>git stash</code> (stash the local changes clean the workspace)\n<code>git merge '@{u}'</code> (merge the changes from local folder to workspace folder)\n<code>git stash pop</code> (apply the latest stash )</p>\n<p>By default, the stash changes will become staged. If you want to unstage them, use <code>git restore --staged</code> (git ver > 2.25.0).</p>\n<h3 id=\"choice-2-you-do-not-want-the-local-changes\" style=\"position:relative;\"><a href=\"#choice-2-you-do-not-want-the-local-changes\" aria-label=\"choice 2 you do not want the local changes 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>Choice 2: you do not want the local changes</h3>\n<p><code>git reset --hard HEAD</code> (reset to the head means remove all local changes)\n<code>git pull</code> (get the latest changes)</p>\n<p>-----------(or)---------------</p>\n<p><code>git fetch</code> (fetch the local machine folder)\n<code>git reset --hard HEAD</code> (reset to the head means remove all local changes)\n<code>git merge '@{u}'</code>  (merge the changes from the local folder to workspace folder)</p>\n<h2 id=\"git-pull---force\" style=\"position:relative;\"><a href=\"#git-pull---force\" aria-label=\"git pull   force 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>git pull --force</h2>\n<p>Now you must be thinking, what is <code>git pull --force</code> then?</p>\n<p>it feels like it would help to overwrite local changes. instead, it fetches forcefully but does not merge forcefully (<code>git pull --force</code> = <code>git fetch --force</code> + <code>git merge</code>).</p>\n<p>Like git push, git fetch allows us to specify which local and remote branch we want to work on. <code>git fetch origin/ft-1:my-ft</code> means the changes in the <code>ft-1</code> branch from the remote repository will end up visible on the local branch <code>my-ft</code>. When such kind of operation modifies the existing history, it is not allowed by the Git without an explicit --force parameter.</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, 2020","updated_date":null,"description":"How to Overwrite Local Changes With Git Force Pull","title":"How to Perform a Git Force Pull","tags":["git"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/496c8e02b6dc1da7410a55bf50a19942/14b42/pull.jpg","srcSet":"/static/496c8e02b6dc1da7410a55bf50a19942/f836f/pull.jpg 200w,\n/static/496c8e02b6dc1da7410a55bf50a19942/2244e/pull.jpg 400w,\n/static/496c8e02b6dc1da7410a55bf50a19942/14b42/pull.jpg 800w,\n/static/496c8e02b6dc1da7410a55bf50a19942/47498/pull.jpg 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Abhimanyu Singh Rathore","github":"abhir9","avatar":null}}}},{"node":{"excerpt":"Introduction In this blog, I will show you how to create a NodeJS server using core http module.  We will create a simple server that will…","fields":{"slug":"/engineering/node-http-module-server/"},"html":"<h3 id=\"introduction\" style=\"position:relative;\"><a href=\"#introduction\" aria-label=\"introduction permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Introduction</h3>\n<p>In this blog, I will show you how to create a NodeJS server using <a href=\"https://nodejs.org/api/http.html\">core http</a> module.  We will create a simple server that will serve static assets and a simple API to return some JSON data. </p>\n<p>In the process, you will also learn about the request and response objects provided by NodeJS, which are used by every other framework built on top of NodeJS like ExpressJS etc. </p>\n<h3 id=\"prerequisites\" style=\"position:relative;\"><a href=\"#prerequisites\" aria-label=\"prerequisites permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Prerequisites</h3>\n<ol>\n<li>NodeJS installed on your system. Download from <a href=\"https://nodejs.org/en/download/\">Here</a></li>\n<li>A basic understanding of JavaScript</li>\n</ol>\n<p>With that in mind, let's begin.</p>\n<h3 id=\"step-1-initialize-the-project\" style=\"position:relative;\"><a href=\"#step-1-initialize-the-project\" aria-label=\"step 1 initialize the project permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 1: Initialize the project</h3>\n<ul>\n<li>\n<p>Create a folder by any name and initialize a node project in it using <code>npm init -y</code></p>\n<ul>\n<li>By this time, you will have a <code>package.json</code> file in your directory.</li>\n</ul>\n</li>\n<li>Create a file called <code>server.js</code> in your directory.</li>\n</ul>\n<h3 id=\"step-2-add-some-static-content\" style=\"position:relative;\"><a href=\"#step-2-add-some-static-content\" aria-label=\"step 2 add some static content permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 2: Add some static content</h3>\n<ul>\n<li>Create a directory called <code>public</code> at the root of your project.</li>\n<li>\n<p>Add a file named <code>index.html</code> with the following content\n<code>index.html</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!</span><span class=\"mtk12\">DOCTYPE</span><span class=\"mtk1\"> </span><span class=\"mtk12\">html</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">html</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lang</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;en&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">charset</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;UTF-8&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;viewport&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;width=device-width, initial-scale=1.0&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Demo</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Coming from the Root </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h3 id=\"step-3-add-our-server-code-to-serve-the-static-assets\" style=\"position:relative;\"><a href=\"#step-3-add-our-server-code-to-serve-the-static-assets\" aria-label=\"step 3 add our server code to serve the static assets permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 3: Add our server code to serve the static assets</h3>\n</li>\n</ul>\n<p>Now we will create a node server that will serve our <code>index.html</code> file when a request is sent to <code>/</code>.</p>\n<p><code>server.js</code></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=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">http</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;http&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">path</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;path&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">fs</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;fs&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">PORT</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">3000</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">hostname</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&#39;localhost&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk3\">// createServer is the http method used to create a web server that takes a callback.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">server</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">http</span><span class=\"mtk1\">.</span><span class=\"mtk11\">createServer</span><span class=\"mtk1\">(</span><span class=\"mtk12\">serverHandler</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk3\">// callback function definition</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">serverHandler</span><span class=\"mtk1\">(</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) =&gt; {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\">(</span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">method</span><span class=\"mtk1\"> === </span><span class=\"mtk8\">&#39;GET&#39;</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">url</span><span class=\"mtk1\"> === </span><span class=\"mtk8\">&#39;/&#39;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">filePath</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">path</span><span class=\"mtk1\">.</span><span class=\"mtk11\">resolve</span><span class=\"mtk1\">(</span><span class=\"mtk12\">__dirname</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;public/index.html&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">fileExists</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">fs</span><span class=\"mtk1\">.</span><span class=\"mtk11\">existsSync</span><span class=\"mtk1\">(</span><span class=\"mtk12\">filePath</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (!</span><span class=\"mtk12\">fileExists</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk12\">statusCode</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">404</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setHeader</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Content-Type&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;text/html&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">end</span><span class=\"mtk1\">(</span><span class=\"mtk8\">`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk8\">          &lt;html&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk8\">            &lt;body&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk8\">              &lt;h3&gt;Page not found&lt;/h3&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk8\">            &lt;/body&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk8\">          &lt;/html&gt;`</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk12\">statusCode</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">200</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setHeader</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Content-Type&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;text/html&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">fs</span><span class=\"mtk1\">.</span><span class=\"mtk11\">createReadStream</span><span class=\"mtk1\">(</span><span class=\"mtk12\">filePath</span><span class=\"mtk1\">).</span><span class=\"mtk11\">pipe</span><span class=\"mtk1\">(</span><span class=\"mtk12\">res</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">server</span><span class=\"mtk1\">.</span><span class=\"mtk11\">listen</span><span class=\"mtk1\">(</span><span class=\"mtk12\">PORT</span><span class=\"mtk1\">, </span><span class=\"mtk12\">hostname</span><span class=\"mtk1\">, () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">`Server running at </span><span class=\"mtk4\">${</span><span class=\"mtk12\">hostname</span><span class=\"mtk4\">}</span><span class=\"mtk8\">:</span><span class=\"mtk4\">${</span><span class=\"mtk12\">PORT</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span><span class=\"mtk1\">);   </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  })</span></span></code></pre>\n<p>Let's understand what just happened in the above code snippet:</p>\n<ul>\n<li>First of all, we just created a server using the <code>createServer</code> method provided by node <code>http</code> module. <code>createServer</code> takes a callback which will be called when there is an incoming request with <code>req</code> and <code>res</code> parameters.</li>\n<li>In our callback function <code>serverHandler</code>, we have used an <code>if</code> block to check if the incoming request is a <code>GET</code> request and the request <code>url</code> is <code>/</code> then code inside if statement will be executed.</li>\n<li>Then, we check if the <code>index.html</code> which we want to serve exists or not in our public directory using <code>existsSync</code>, which synchronously checks for the file at the given path and returns true if the file exists.</li>\n<li>Then if the file does not exist, we return a 404 status with an HTML response with a Content-Type header to let the browser know that it's an HTML type response.</li>\n<li>If the file exists, we create a readable stream from it using <code>createReadStream</code> method from <code>fs</code> module and pipe it into <code>res</code> object which sends it to the browser.</li>\n<li>Finally, we use <code>server.listen</code> to start our server on the PORT 3000.</li>\n</ul>\n<p>Now it's time to test our server. Run <code>node server.js</code> at the root of the project, and you will see the server running on PORT 3000.\nOpen your browser and enter <code>localhost:3000</code> in the address bar, and you will get the HTML response. </p>\n<h3 id=\"step-4-add-a-basic-api-to-return-some-json-data\" style=\"position:relative;\"><a href=\"#step-4-add-a-basic-api-to-return-some-json-data\" aria-label=\"step 4 add a basic api to return some json data permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 4: Add a basic API to return some JSON data</h3>\n<p>Now we will expand our callback, which we passed to <code>createServer</code> to handle one more <code>GET</code> request at <code>/notes</code>, which will return an array of notes to the browser.</p>\n<p>Update the <code>serverHandler</code> function with the following code snippet in your <code>server.js</code> file</p>\n<p><code>server.js</code></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=\"mtk1\">  ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">serverHandler</span><span class=\"mtk1\">(</span><span class=\"mtk12\">req</span><span class=\"mtk1\">, </span><span class=\"mtk12\">res</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">if</span><span class=\"mtk1\">(</span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">method</span><span class=\"mtk1\"> === </span><span class=\"mtk8\">&#39;GET&#39;</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">url</span><span class=\"mtk1\"> === </span><span class=\"mtk8\">&#39;/&#39;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">filePath</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">path</span><span class=\"mtk1\">.</span><span class=\"mtk11\">resolve</span><span class=\"mtk1\">(</span><span class=\"mtk12\">__dirname</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;public/index.html&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">fileExists</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">fs</span><span class=\"mtk1\">.</span><span class=\"mtk11\">existsSync</span><span class=\"mtk1\">(</span><span class=\"mtk12\">filePath</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (!</span><span class=\"mtk12\">fileExists</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk12\">statusCode</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">404</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setHeader</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Content-Type&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;text/html&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">end</span><span class=\"mtk1\">(</span><span class=\"mtk8\">`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk8\">            &lt;html&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk8\">              &lt;body&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk8\">                &lt;h3&gt;Page not found&lt;/h3&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk8\">              &lt;/body&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk8\">            &lt;/html&gt;`</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk12\">statusCode</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">200</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setHeader</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Content-Type&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;text/html&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk12\">fs</span><span class=\"mtk1\">.</span><span class=\"mtk11\">createReadStream</span><span class=\"mtk1\">(</span><span class=\"mtk12\">filePath</span><span class=\"mtk1\">).</span><span class=\"mtk11\">pipe</span><span class=\"mtk1\">(</span><span class=\"mtk12\">res</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk3\">// Newly added code </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">method</span><span class=\"mtk1\"> === </span><span class=\"mtk8\">&#39;GET&#39;</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">url</span><span class=\"mtk1\"> === </span><span class=\"mtk8\">&quot;/notes&quot;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">notes</span><span class=\"mtk1\"> = [</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">1</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">title:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Demo Note&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">2</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">title:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Another Note&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        ]</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk12\">statusCode</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">200</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setHeader</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Content-Type&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">end</span><span class=\"mtk1\">(</span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">(</span><span class=\"mtk12\">notes</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setHeader</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Content-Type&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;application/json&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">end</span><span class=\"mtk1\">(</span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">({</span><span class=\"mtk12\">message:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">`</span><span class=\"mtk4\">${</span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">method</span><span class=\"mtk4\">}</span><span class=\"mtk8\"> is not supported for </span><span class=\"mtk4\">${</span><span class=\"mtk12\">req</span><span class=\"mtk1\">.</span><span class=\"mtk12\">url</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span><span class=\"mtk1\">}))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      } </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ...</span></span></code></pre>\n<ul>\n<li>Here, we have added one more <code>if</code> statement to handle the request coming at <code>/notes</code> .</li>\n<li>We return a notes array in the JSON format, and we are setting the Content-Type header to be of <code>application/json</code> for the browser to process it accordingly.</li>\n<li>We have also added an else statement to handle all other requests where we simply return a message to the browser that the request is not supported.</li>\n</ul>\n<p>With that, we have created a simple node server to serve static content as well a simple API to return JSON data. </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>We saw how we had to handle each request with its method and the URL. With an increasing number of routes, such things become hard to manage as we will have to add multiple if statements. And that's why frameworks like ExpressJS, HapiJS exist, which makes creating servers in NodeJS very easy. But it's important to know what happens under the hood as there is no magic happening in those frameworks.</p>\n<p>The complete code for this blog can be found at <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/NodeJs/NodeHTTPServer\">Github Repo</a>.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk17 { color: #808080; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n</style>","frontmatter":{"date":"November 27, 2020","updated_date":null,"description":"Let us understand the core http module in NodeJS, which is the basic building block of frameworks like ExpressJS etc.","title":"NodeJS Server using Core HTTP Module","tags":["NodeJs","JavaScript"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/6ee159acf6c294342ec04f86aede5d14/14b42/coverImage.jpg","srcSet":"/static/6ee159acf6c294342ec04f86aede5d14/f836f/coverImage.jpg 200w,\n/static/6ee159acf6c294342ec04f86aede5d14/2244e/coverImage.jpg 400w,\n/static/6ee159acf6c294342ec04f86aede5d14/14b42/coverImage.jpg 800w,\n/static/6ee159acf6c294342ec04f86aede5d14/47498/coverImage.jpg 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Hridayesh Sharma","github":"vyasriday","avatar":null}}}},{"node":{"excerpt":"How does bitwise ^ (XOR) work? XOR is a bitwise operator, and it stands for \"exclusive or.\" It performs logical operation. If input bits are…","fields":{"slug":"/engineering/how-does-bitwise-xor-work/"},"html":"<h2 id=\"how-does-bitwise--xor-work\" style=\"position:relative;\"><a href=\"#how-does-bitwise--xor-work\" aria-label=\"how does bitwise  xor 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>How does bitwise ^ (XOR) work?</h2>\n<p>XOR is a bitwise operator, and it stands for \"exclusive or.\" It performs <strong>logical</strong> operation. If input bits are the same, then the output will be false(0) else true(1).</p>\n<p>XOR table:</p>\n<table>\n<thead>\n<tr>\n<th>X</th>\n<th>Y</th>\n<th>X^Y</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>0</td>\n<td>0</td>\n<td>0</td>\n</tr>\n<tr>\n<td>0</td>\n<td>1</td>\n<td>1</td>\n</tr>\n<tr>\n<td>1</td>\n<td>0</td>\n<td>1</td>\n</tr>\n<tr>\n<td>1</td>\n<td>1</td>\n<td>0</td>\n</tr>\n</tbody>\n</table>\n<p>Example:  <code>4^3 = 7</code></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=\"mtk12\">In</span><span class=\"mtk1\"> binary: </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t     </span><span class=\"mtk7\">0100</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t   ^ </span><span class=\"mtk7\">0011</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t    ------</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> Result: </span><span class=\"mtk7\">0111</span><span class=\"mtk1\">  </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> (</span><span class=\"mtk7\">7</span><span class=\"mtk1\">)</span></span></code></pre>\n<h4 id=\"xor-with-negative-numbers\" style=\"position:relative;\"><a href=\"#xor-with-negative-numbers\" aria-label=\"xor with negative numbers 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>XOR with negative numbers</h4>\n<p>Let's understand with an example <code>-4^-2 = 2</code>\nIn the above example, we can see <code>-4^-2</code>output will be <code>2</code>\nbut the question arises how? Because if we represent both inputs in the binary form, then we do XOR of bits, then the output will be <code>0000 0110</code> and in decimal, it will be <code>6</code> but as we know output should be <code>2</code>.</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=\"mtk1\">  </span><span class=\"mtk7\">1000</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0100</span><span class=\"mtk1\"> (-</span><span class=\"mtk7\">4</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">^ </span><span class=\"mtk7\">1000</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0010</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=\"mtk1\">  </span><span class=\"mtk7\">0000</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0110</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> (</span><span class=\"mtk7\">6</span><span class=\"mtk1\">) </span><span class=\"mtk3\">// incorrect output</span></span></code></pre>\n<blockquote>\n<p>Note: Here, the leftmost bit position is reserved for the sign of the\nvalue (positive or negative) and doesn't contribute towards the value of the number.</p>\n</blockquote>\n<p> Let's understand how the XOR operation works with negative numbers.</p>\n<h5 id=\"how-xor-operation-works-with-negative-numbers\" style=\"position:relative;\"><a href=\"#how-xor-operation-works-with-negative-numbers\" aria-label=\"how xor operation works with negative numbers 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 XOR operation works with negative numbers?</h5>\n<p>First, the XOR operation is to XOR each bit (the same is 0, the difference is 1), but you need to convert the number into a complement first.</p>\n<ol>\n<li>The complement of a positive number is itself</li>\n<li>\n<p>The complement of the negative number is reversed for each bit and then incremented by 1 (the highest is kept at 1)</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=\"mtk3\">// Lets take -4</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">In</span><span class=\"mtk1\"> binary: \t\t\t</span><span class=\"mtk7\">1000</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0100</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">Reverse: \t\t\t</span><span class=\"mtk7\">1111</span><span class=\"mtk1\"> </span><span class=\"mtk7\">1011</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">complement</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">Increment</span><span class=\"mtk1\"> </span><span class=\"mtk12\">by</span><span class=\"mtk1\"> </span><span class=\"mtk7\">1</span><span class=\"mtk1\">): \t</span><span class=\"mtk7\">1111</span><span class=\"mtk1\"> </span><span class=\"mtk7\">1100</span></span></code></pre>\n</li>\n</ol>\n<p>// Now -2\nIn binary: \t\t\t1000 0010\nReverse: \t\t\t1111 1101\ncomplement (Increment by 1): \t1111 1110</p>\n<p>Final result:</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=\"mtk12\">complement</span><span class=\"mtk1\"> </span><span class=\"mtk4\">of</span><span class=\"mtk1\"> -</span><span class=\"mtk7\">4</span><span class=\"mtk1\"> : </span><span class=\"mtk7\">1111</span><span class=\"mtk1\"> </span><span class=\"mtk7\">1100</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">complement</span><span class=\"mtk1\"> </span><span class=\"mtk4\">of</span><span class=\"mtk1\"> -</span><span class=\"mtk7\">2</span><span class=\"mtk1\"> : </span><span class=\"mtk7\">1111</span><span class=\"mtk1\"> </span><span class=\"mtk7\">1110</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                  -----------</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">Result:            </span><span class=\"mtk7\">0000</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0010</span><span class=\"mtk1\"> \t</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk7\">2</span></span></code></pre>\n<p><em>Here, the MSB bit of result will denote the sign, and the rest of the bits will denote the value of the final result.</em>\nXOR sign table could be useful to understand the sign of result:</p>\n<table>\n<thead>\n<tr>\n<th>X</th>\n<th>Y</th>\n<th>X^Y</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>+</td>\n<td>+</td>\n<td>+</td>\n</tr>\n<tr>\n<td>+</td>\n<td>-</td>\n<td>-</td>\n</tr>\n<tr>\n<td>-</td>\n<td>+</td>\n<td>-</td>\n</tr>\n<tr>\n<td>-</td>\n<td>-</td>\n<td>+</td>\n</tr>\n</tbody>\n</table>\n<p>The above approach will work with negative inputs, but if we have positive and negative, then? </p>\n<h5 id=\"how-xor-operation-works-with-positive-and-negative-numbers\" style=\"position:relative;\"><a href=\"#how-xor-operation-works-with-positive-and-negative-numbers\" aria-label=\"how xor operation works with positive and negative numbers 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 XOR operation works with positive and negative numbers?</h5>\n<p>Let's performs <code>-5 ^ 2</code>\nFollow the same above approach to get a complement code of <code>-5</code>.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">complement</span><span class=\"mtk1\"> </span><span class=\"mtk4\">of</span><span class=\"mtk1\"> -</span><span class=\"mtk7\">5</span><span class=\"mtk1\"> :          </span><span class=\"mtk7\">1111</span><span class=\"mtk1\"> </span><span class=\"mtk7\">1011</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// Note: complement of a positive number is itself</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">complement</span><span class=\"mtk1\"> </span><span class=\"mtk4\">of</span><span class=\"mtk1\"> </span><span class=\"mtk7\">2</span><span class=\"mtk1\"> :           </span><span class=\"mtk7\">0000</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0010</span><span class=\"mtk1\">  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">complement</span><span class=\"mtk1\"> result:          </span><span class=\"mtk7\">1111</span><span class=\"mtk1\"> </span><span class=\"mtk7\">1001</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">Now</span><span class=\"mtk1\">, </span><span class=\"mtk12\">complement</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\"> -</span><span class=\"mtk7\">1</span><span class=\"mtk1\"> : </span><span class=\"mtk7\">1111</span><span class=\"mtk1\"> </span><span class=\"mtk7\">1000</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                           -----------</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">Final</span><span class=\"mtk1\"> </span><span class=\"mtk11\">result</span><span class=\"mtk1\">(</span><span class=\"mtk12\">inverse</span><span class=\"mtk1\"> </span><span class=\"mtk12\">code</span><span class=\"mtk1\">): </span><span class=\"mtk7\">1000</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0111</span><span class=\"mtk1\">   </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> -</span><span class=\"mtk7\">7</span></span></code></pre>\n<h4 id=\"some-interesting-use-cases-of-xor-operator\" style=\"position:relative;\"><a href=\"#some-interesting-use-cases-of-xor-operator\" aria-label=\"some interesting use cases of xor operator 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>Some interesting use cases of XOR operator</h4>\n<ul>\n<li>\n<p>Swap two number without the third variable\nExample:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">swapWithXOR</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">a</span><span class=\"mtk1\">, </span><span class=\"mtk12\">b</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">a</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">a</span><span class=\"mtk1\">^</span><span class=\"mtk12\">b</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">b</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">a</span><span class=\"mtk1\">^</span><span class=\"mtk12\">b</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">a</span><span class=\"mtk1\">=</span><span class=\"mtk12\">a</span><span class=\"mtk1\">^</span><span class=\"mtk12\">b</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;result =&gt; a: &quot;</span><span class=\"mtk1\"> + </span><span class=\"mtk12\">a</span><span class=\"mtk1\"> + </span><span class=\"mtk8\">&quot;, b: &quot;</span><span class=\"mtk1\"> + </span><span class=\"mtk12\">b</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">swapWithXOR</span><span class=\"mtk1\">(</span><span class=\"mtk7\">4</span><span class=\"mtk1\">, </span><span class=\"mtk7\">1</span><span class=\"mtk1\">); </span><span class=\"mtk3\">// result =&gt; a: 1, b: 4</span></span></code></pre>\n</li>\n<li>RAID Drive Backups (Systems)</li>\n<li>Cryptography (XOR cipher)</li>\n<li>Array operations</li>\n</ul>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n</style>","frontmatter":{"date":"November 24, 2020","updated_date":null,"description":"Everything you should know about bitwise ^ xor operator.","title":"How does bitwise ^ (XOR) work?","tags":["bitwise","XOR"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/6918df91209eb3e5939b47bc7ec1d346/ee604/xor.png","srcSet":"/static/6918df91209eb3e5939b47bc7ec1d346/69585/xor.png 200w,\n/static/6918df91209eb3e5939b47bc7ec1d346/497c6/xor.png 400w,\n/static/6918df91209eb3e5939b47bc7ec1d346/ee604/xor.png 800w,\n/static/6918df91209eb3e5939b47bc7ec1d346/f3583/xor.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Kheenvraj Lomror","github":"rajlomror","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":102,"currentPage":18,"type":"//engineering//","numPages":52,"pinned":"17fa0d7b-34c8-51c4-b047-df5e2bbaeedb"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}