{
    "componentChunkName": "component---src-pages-blog-markdown-remark-fields-slug-js",
    "path": "/blog/adding-social-login-to-your-website-with-supertokens",
    "result": {"data":{"markdownRemark":{"html":"<p>This tutorial walks you through building your own social login UI using SuperTokens.</p>\n<blockquote>\n<p>Note, that it’s only meant for users who are building their own frontend and are building a website. This blog is not meant for users using our pre-built UI.</p>\n</blockquote>\n<p>To start off, you want to make sure that you have finished the frontend and backend quick setup guides for <a href=\"https://supertokens.com/docs/community/recipes\" target=\"_blank\" rel=\"nofollow\">the recipe</a> that you have chosen.</p>\n<p>As of this writing, that’s either:</p>\n<ul>\n<li><a href=\"https://supertokens.com/docs/thirdparty/introduction\" target=\"_blank\" rel=\"nofollow\">ThirdParty recipe</a> (only social login)</li>\n<li><a href=\"https://supertokens.com/docs/thirdpartyemailpassword/introduction\" target=\"_blank\" rel=\"nofollow\">ThirdPartyEmailPassword recipe</a> (social + email password login)</li>\n</ul>\n<p><strong>For ease of explanation, we will assume the following:</strong></p>\n<p>We want to implement sign in with GitHub</p>\n<ul>\n<li>Your website domain is <code class=\"language-text\">http://localhost:3000</code></li>\n<li>Your API domain is <code class=\"language-text\">http://localhost:3001</code></li>\n<li>You have chosen the default <code class=\"language-text\">apiBasePath</code> and <code class=\"language-text\">websiteBasePath</code> (<code class=\"language-text\">/auth</code> in both the cases)</li>\n<li>You want to implement the <strong>thirdpartyemailpassword</strong> recipe.</li>\n<li>The authorisation redirect URL set on the GitHub dashboard is <code class=\"language-text\">http://localhost:3000/auth/callback/github</code>.</li>\n<li>We will be using the <a href=\"https://github.com/supertokens/supertokens-web-js\" target=\"_blank\" rel=\"nofollow\">supertokens-web-js SDK</a>, so we assume that you have initilaised that in your app already (as shown in the recipe setup guide)</li>\n</ul>\n<p>On a high level, there are two steps to the flow:</p>\n<ul>\n<li>When the user clicks on the <code class=\"language-text\">Sign in with GitHub</code> button, you want to fetch the GitHub redirect URL and redirect the user to that page. This is where the user will interact with GitHub to enter their credentials.</li>\n<li>When GitHub redirects the user back to your app, you want to use the (one time use) auth code issued by Github to sign in / sign up the user.</li>\n</ul>\n<h3 id=\"step-1\" style=\"position:relative;\"><a href=\"#step-1\" aria-label=\"step 1 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 1</h3>\n<p>When the user clicks on <code class=\"language-text\">Sign in with GitHub</code> button, you want to call the following function using the <code class=\"language-text\">supertokens-web-js</code> SDK</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"55523069258645470000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied!\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`import ThirdPartyEmailPassword from &quot;supertokens-web-js/recipe/thirdpartyemailpassword&quot;\n\nasync function loginWithGitHubClicked() {\n  let githubAuthURL = await ThirdPartyEmailPassword.getAuthorisationURLWithQueryParamsAndSetState({\n    authorisationURL: &quot;http://localhost:3000/auth/callback/github&quot;,\n    providerId: &quot;github&quot;\n  })\n\n  // an example value of githubAuthURL is\n  // https://github.com/login/oauth/authorize?scope=read%3Auser+user%3Aemail&client_id=21d82062d1f35b68e66c\n\n  // we redirect the user to sign in with github\n  window.location.href = githubAuthURL\n}`, `55523069258645470000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> ThirdPartyEmailPassword <span class=\"token keyword\">from</span> <span class=\"token string\">\"supertokens-web-js/recipe/thirdpartyemailpassword\"</span>\n\n<span class=\"token keyword\">async</span> <span class=\"token keyword\">function</span> <span class=\"token function\">loginWithGitHubClicked</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">let</span> githubAuthURL <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> ThirdPartyEmailPassword<span class=\"token punctuation\">.</span><span class=\"token function\">getAuthorisationURLWithQueryParamsAndSetState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n    <span class=\"token literal-property property\">authorisationURL</span><span class=\"token operator\">:</span> <span class=\"token string\">\"http://localhost:3000/auth/callback/github\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token literal-property property\">providerId</span><span class=\"token operator\">:</span> <span class=\"token string\">\"github\"</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token comment\">// an example value of githubAuthURL is</span>\n  <span class=\"token comment\">// https://github.com/login/oauth/authorize?scope=read%3Auser+user%3Aemail&amp;client_id=21d82062d1f35b68e66c</span>\n\n  <span class=\"token comment\">// we redirect the user to sign in with github</span>\n  window<span class=\"token punctuation\">.</span>location<span class=\"token punctuation\">.</span>href <span class=\"token operator\">=</span> githubAuthURL\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The URL returned in the response of calling <code class=\"language-text\">getAuthorisationURLWithQueryParamsAndSetState</code> is where you will redirect your user to.</p>\n<h3 id=\"step-2\" style=\"position:relative;\"><a href=\"#step-2\" aria-label=\"step 2 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</h3>\n<p>When the user is navigated back to your app (from GitHub), the URL will contain a <code class=\"language-text\">code</code> query param (on successful login), like this:</p>\n<p><code class=\"language-text\">http://localhost:3000/auth/callback/github?code=3cf143e0af0f1bed8d34</code></p>\n<p>First, you want to create a page on your frontend app which will handle this route (<code class=\"language-text\">/auth/callback/github</code>). On this page, you want to show a loading spinner, and call the following function from our SDK:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"7830920494230153000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied!\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`import ThirdPartyEmailPassword from &quot;supertokens-web-js/recipe/thirdpartyemailpassword&quot;\n\nasync function consumeAuthCodeAndLoginUser() {\n  let result = await ThirdPartyEmailPassword.thirdPartySignInAndUp();\n\n  if (result.status === &quot;OK&quot;) {\n    if (result.createdNewUser) {\n      // user sign up\n    } else {\n      // user sign in\n    }\n  } else {\n    // TODO: this means that the user does not have\n    // an email associated with their GitHub account.\n    // Ask them to sign in using another method.\n  }\n}`, `7830920494230153000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> ThirdPartyEmailPassword <span class=\"token keyword\">from</span> <span class=\"token string\">\"supertokens-web-js/recipe/thirdpartyemailpassword\"</span>\n\n<span class=\"token keyword\">async</span> <span class=\"token keyword\">function</span> <span class=\"token function\">consumeAuthCodeAndLoginUser</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">let</span> result <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> ThirdPartyEmailPassword<span class=\"token punctuation\">.</span><span class=\"token function\">thirdPartySignInAndUp</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>result<span class=\"token punctuation\">.</span>status <span class=\"token operator\">===</span> <span class=\"token string\">\"OK\"</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>result<span class=\"token punctuation\">.</span>createdNewUser<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token comment\">// user sign up</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token comment\">// user sign in</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// TODO: this means that the user does not have</span>\n    <span class=\"token comment\">// an email associated with their GitHub account.</span>\n    <span class=\"token comment\">// Ask them to sign in using another method.</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>When we call the <code class=\"language-text\">thirdPartySignInAndUp</code> function, it extracts the <code class=\"language-text\">code</code> from the query params and sends it to the backend. The backend then exchanges that code with Github to get the user’s information and create a new session.</p>\n<h2 id=\"where-are-the-session-tokens\" style=\"position:relative;\"><a href=\"#where-are-the-session-tokens\" aria-label=\"where are the session tokens permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Where are the session tokens?</h2>\n<p>From inspecting the <code class=\"language-text\">result</code> variable from the above code snippet, we don’t see an access token / JWT in the response body - so where are they?</p>\n<p>SuperTokens issues session cookies that get sent via the <code class=\"language-text\">Set-Cookie</code> header in the API response and is automatically handled by the browser.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/574580f5e0f8a363d70398be700c7863/29007/set-cookie-header.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 19.62025316455696%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAn0lEQVQI1z3O2w6DIAyAYR9lMxNBhVpqKQeP7/9SC5ot+dN8TS+gQc+Ay2jROj+5Oi14C2jBu5ncTBWPwQMu95UsECA3LKVsV17Psl2xHI9j3mPeH0jaUjnyekraiNMS7jgTxwZJWApLDnG9UV37rUjiSZACIN/v154PNkiBY8ElshQKmTiZwSk9amN7PWljlR47ZVQ/dMq82s+77f59AUYLL0kl3rp9AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Set-Cookie Header\"\n        title=\"Set-Cookie Header\"\n        src=\"/static/574580f5e0f8a363d70398be700c7863/f058b/set-cookie-header.png\"\n        srcset=\"/static/574580f5e0f8a363d70398be700c7863/c26ae/set-cookie-header.png 158w,\n/static/574580f5e0f8a363d70398be700c7863/6bdcf/set-cookie-header.png 315w,\n/static/574580f5e0f8a363d70398be700c7863/f058b/set-cookie-header.png 630w,\n/static/574580f5e0f8a363d70398be700c7863/40601/set-cookie-header.png 945w,\n/static/574580f5e0f8a363d70398be700c7863/78612/set-cookie-header.png 1260w,\n/static/574580f5e0f8a363d70398be700c7863/29007/set-cookie-header.png 1600w\"\n        sizes=\"(max-width: 630px) 100vw, 630px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>Furthermore, our frontend SDK handles these session tokens for you automatically:</p>\n<ul>\n<li>Automatic refresh of session</li>\n<li>Automatic injection of the access token for your API calls</li>\n<li>Provides a <code class=\"language-text\">signOut</code> function</li>\n</ul>\n<p>These features are a part of the session recipe that you initialized when following the quick setup guide.</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>We have seen how to integrate your custom UI with the social login functions exposed by SuperToken’s frontend SDK. Furthermore, we see that on successful login, we are issued cookie based session tokens which are handled automatically by SuperTokens.</p>","frontmatter":{"date":"January 26, 2022","title":"Adding social login to your website with SuperTokens (custom UI only)","cover":"adding-social-login-to-your-website-with-supertokens.png","author":"Rishabh Poddar","description":"This blog walks you through integrating your frontend with social login APIs provided by SuperTokens."},"fields":{"slug":"/adding-social-login-to-your-website-with-supertokens/"}},"site":{"siteMetadata":{"title":"SuperTokens Blog"}}},"pageContext":{"id":"3dd32e6e-0a18-5501-8f6e-45384f2d2d5b","fields__slug":"/adding-social-login-to-your-website-with-supertokens/","__params":{"fields__slug":"adding-social-login-to-your-website-with-supertokens"}}},
    "staticQueryHashes": []}