Skip to main content

Social login

There are different flows that the third party login provider may support:

  • Flow 1) Via authorisation code (one time use code) - for web and mobile apps.
    • a) If you have configred the client secret on the backend:
      • The frontend sends the auth code to the backend, the backend exchanges that with the provided client secret to get the access token. The access token is then used to fetch user info and log them in.
    • b) If you have not provided the client secret on the backend:
      • The backend uses PKCE flow to exchange the auth code with the user's access token. The access token is then used to fetch user info and log them in.
  • Flow 2) Via OAuth / access tokens - for mobile apps.
    • The access token is available on the frontend and is sent to the backend. SuperTokens then fetches user info using the access token and logs them in.
note

The same flow applies during sign up and sign in. If the user is signing up, the createdNewUser boolean on the frontend and backend will be true (as the result of the sign in up API call).

Flow 1a: Authorization code grant flow (Sign in with Google example)

Step 1) Redirecting to social / SSO provider

The first step is to fetch the URL on which the user will be authenticated. This can be done by querying the backend API exposed by SuperTokens (as shown below). The backend SDK automatically appends the right query params to the URL (like scope, client ID etc).

After we get the URL, we simply redirect the user there. In the code below, we will take an example of login with Google:

import { getAuthorisationURLWithQueryParamsAndSetState } from "supertokens-web-js/recipe/thirdpartyemailpassword";

async function googleSignInClicked() {
try {
const authUrl = await getAuthorisationURLWithQueryParamsAndSetState({
thirdPartyId: "google",

// This is where Google should redirect the user back after login or error.
// This URL goes on the Google's dashboard as well.
frontendRedirectURI: "http://<YOUR_WEBSITE_DOMAIN>/auth/callback/google",
});

/*
Example value of authUrl: https://accounts.google.com/o/oauth2/v2/auth/oauthchooseaccount?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&access_type=offline&include_granted_scopes=true&response_type=code&client_id=1060725074195-kmeum4crr01uirfl2op9kd5acmi9jutn.apps.googleusercontent.com&state=5a489996a28cafc83ddff&redirect_uri=https%3A%2F%2Fsupertokens.io%2Fdev%2Foauth%2Fredirect-to-app&flowName=GeneralOAuthFlow
*/

// we redirect the user to google for auth.
window.location.assign(authUrl);
} catch (err: any) {
if (err.isSuperTokensGeneralError === true) {
// this may be a custom error message sent from the API by you.
window.alert(err.message);
} else {
window.alert("Oops! Something went wrong.");
}
}
}

Step 2) Handling the auth callback on your frontend

Once the third party provider redirects your user back to your app, you need to consume the information to sign in the user. This requires you to:

  • Setup a route in your app that will handle this callback. We recommend something like http://<YOUR_WEBSITE_DOMAIN>/auth/callback/google (for Google). Regardless of what you make this path, remember to use that same path when calling the getAuthorisationURLWithQueryParamsAndSetState function in the first step.

  • On that route, call the following function on page load

    import { thirdPartySignInAndUp } from "supertokens-web-js/recipe/thirdpartyemailpassword";

    async function handleGoogleCallback() {
    try {
    const response = await thirdPartySignInAndUp();

    if (response.status === "OK") {
    console.log(response.user)
    if (response.createdNewRecipeUser && response.user.loginMethods.length === 1) {
    // sign up successful
    } else {
    // sign in successful
    }
    window.location.assign("/home");
    } else if (response.status === "SIGN_IN_UP_NOT_ALLOWED") {
    // the reason string is a user friendly message
    // about what went wrong. It can also contain a support code which users
    // can tell you so you know why their sign in / up was not allowed.
    window.alert(response.reason)
    } else {
    // SuperTokens requires that the third party provider
    // gives an email for the user. If that's not the case, sign up / in
    // will fail.

    // As a hack to solve this, you can override the backend functions to create a fake email for the user.

    window.alert("No email provided by social login. Please use another form of login");
    window.location.assign("/auth"); // redirect back to login page
    }
    } catch (err: any) {
    if (err.isSuperTokensGeneralError === true) {
    // this may be a custom error message sent from the API by you.
    window.alert(err.message);
    } else {
    window.alert("Oops! Something went wrong.");
    }
    }
    }
note

On success, the backend will send back session tokens as part of the response headers which will be automatically handled by our frontend SDK for you.

Special case for login with Apple

Unlike other providers, Apple will not redirect your user back to your frontend app. Instead, it will redirect the user to your backend with a FORM POST request. This means that the URL that you configure on the Apple's dashboard should point to your backend API layer in which our middleware will handle the request and redirect the user to your frontend app. Your frontend app should then call the thirdPartySignInAndUp API on that page as shown previously.

In order to tell SuperTokens which frontend route to redirect the user back to, you need to set the frontendRedirectURI to the frontend route (just like for other providers), and also need to set the redirectURIOnProviderDashboard to point to your backend API route (to which Apple will send a POST request).

import { getAuthorisationURLWithQueryParamsAndSetState } from "supertokens-web-js/recipe/thirdpartyemailpassword";

async function appleSignInClicked() {
try {
const authUrl = await getAuthorisationURLWithQueryParamsAndSetState({
thirdPartyId: "apple",

frontendRedirectURI: "http://localhost:3000/auth/callback/apple", // This is an example callback URL on your frontend. You can use another path as well.
redirectURIOnProviderDashboard: "<YOUR_API_DOMAIN>/auth/callback/apple", // This URL goes on the Apple's dashboard
});

// we redirect the user to apple for auth.
window.location.assign(authUrl);
} catch (err: any) {
if (err.isSuperTokensGeneralError === true) {
// this may be a custom error message sent from the API by you.
window.alert(err.message);
} else {
window.alert("Oops! Something went wrong.");
}
}
}

Flow 1b: Authorization code grant flow with PKCE

This is identical to flow 1a, except that you do not need to provide a client secret during backend init. This flow only works for providers which support the PKCE flow.

Flow 2: Via OAuth / Access token

caution

This flow is not applicable for web apps.

Social / SSO login for both, web and mobile apps#

If you have social / SSO login for your web and mobile app, then you might need to setup different client ID / secret for the same provider on the backend. For example, in case of Apple login, Apple gives you different client IDs for iOS login vs web & Android login (same client ID for web and Android).

In order to get this to work, you would need to add additional clients to the Apple.init on the backend. Each client would need to be uniquely identified and this is done using the clientType string. For example, you can add one clientType for web-and-android and one for ios.

import { ThirdPartyProviderInput } from "supertokens-node/recipe/thirdpartyemailpassword/types";

let providers: ThirdPartyProviderInput[] = [
{
config: {
thirdPartyId: "apple",
clients: [{
clientType: "web-and-android",
clientId: "...",
additionalConfig: {
"keyId": "...",
"privateKey": "...",
"teamId": "...",
}
}, {
clientType: "ios",
clientId: "...",
additionalConfig: {
"keyId": "...",
"privateKey": "...",
"teamId": "...",
}
}]
}
}
]

For the frontend, you would need to use the right clientType as shown below:

We pass in the clientType during the init call.

import SuperTokens from 'supertokens-web-js';

SuperTokens.init({
appInfo: {
apiDomain: "<YOUR_API_DOMAIN>",
apiBasePath: "/auth",
appName: "...",
},
clientType: "web-and-android",
recipeList: [/*...*/],
});

If you are using our pre built UI SDK (supertokens-auth-react) as well, you can provide the clientType config to it as follows:

import SuperTokens from 'supertokens-auth-react';

SuperTokens.init({
appInfo: {
apiDomain: "<YOUR_API_DOMAIN>",
websiteDomain: "<YOUR_WEBSITE_DOMAIN>",
apiBasePath: "/auth",
appName: "...",
},
clientType: "web-and-android",
recipeList: [/*...*/],
});

See also#

Looking for older versions of the documentation?
Which UI do you use?
Custom UI
Pre built UI