Post signin / signup callbacks
#
1) On the frontendThis method allows you to fire events immediately after a successful sign in / up. For example to send analytics events post sign in / up.
- ReactJS
- Angular
- Vue
- Plain JavaScript
- React Native
Note
You can use the
You can refer to this example app as a reference for using the
supertokens-web-js
SDK which exposes several helper functions that query the APIs exposed by the SuperTokens backend SDK.You can refer to this example app as a reference for using the
supertokens-web-js
SDK.Note
To use SuperTokens with React Native you need to use the
To add login functionality, you need to build your own UI and call the APIs exposed by the backend SDKs. You can find the API spec here
supertokens-react-native
SDK. The SDK provides session management features.To add login functionality, you need to build your own UI and call the APIs exposed by the backend SDKs. You can find the API spec here
What type of UI are you using?
Prebuilt UICustom UI
What type of UI are you using?
Prebuilt UICustom UI
import SuperTokens from "supertokens-auth-react";
import ThirdPartyEmailPassword from "supertokens-auth-react/recipe/thirdpartyemailpassword";
import Session from "supertokens-auth-react/recipe/session";
SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
ThirdPartyEmailPassword.init({
onHandleEvent: async (context) => {
if (context.action === "SESSION_ALREADY_EXISTS") {
// TODO:
} else if (context.action === "SUCCESS") {
let { id, email } = context.user;
if (context.isNewUser) {
// TODO: Sign up
} else {
// TODO: Sign in
}
}
}
}),
Session.init()
]
});
info
Please refer to this page to learn more about the onHandleEvent
hook.
#
2) On the backend- NodeJS
- GoLang
- Python
- >= v8.0.0
- < v8.0.0
For this, you'll have to override the following APIs in the init
function call, on the backend:
emailPasswordSignUpPOST
: Sign up with email & passwordemailPasswordSignInPOST
: Sign in with email & passwordthirdPartySignInUpPOST
: Sign in or up with third party
import SuperTokens from "supertokens-node";
import ThirdPartyEmailPassword from "supertokens-node/recipe/thirdpartyemailpassword";
import Session from "supertokens-node/recipe/session";
SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
supertokens: {
connectionURI: "...",
},
recipeList: [
ThirdPartyEmailPassword.init({
override: {
apis: (originalImplementation) => {
return {
...originalImplementation,
// override the email password sign up API
emailPasswordSignUpPOST: async function(input) {
if (originalImplementation.emailPasswordSignUpPOST === undefined) {
throw Error("Should never come here");
}
// TODO: some pre sign up logic
let response = await originalImplementation.emailPasswordSignUpPOST(input);
if (response.status === "OK") {
// TODO: some post sign up logic
}
return response;
},
// override the email password sign in API
emailPasswordSignInPOST: async function(input) {
if (originalImplementation.emailPasswordSignInPOST === undefined) {
throw Error("Should never come here");
}
// TODO: some pre sign in logic
let response = await originalImplementation.emailPasswordSignInPOST(input);
if (response.status === "OK") {
// TODO: some post sign in logic
}
return response;
},
// override the thirdparty sign in / up API
thirdPartySignInUpPOST: async function(input) {
if (originalImplementation.thirdPartySignInUpPOST === undefined) {
throw Error("Should never come here");
}
// TODO: Some pre sign in / up logic
let response = await originalImplementation.thirdPartySignInUpPOST(input);
if (response.status === "OK") {
if (response.createdNewUser) {
// TODO: some post sign up logic
} else {
// TODO: some post sign in logic
}
}
return response;
}
}
}
}
}),
Session.init({ /* ... */ })
]
});
For this, you'll have to override the signInUpPOST
API in the init
function call.
import SuperTokens from "supertokens-node";
import ThirdPartyEmailPassword from "supertokens-node/recipe/thirdpartyemailpassword";
import Session from "supertokens-node/recipe/session";
SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
supertokens: {
connectionURI: "...",
},
recipeList: [
ThirdPartyEmailPassword.init({
override: {
apis: (originalImplementation) => {
return {
...originalImplementation,
signInUpPOST: async function (input) {
if (originalImplementation.signInUpPOST === undefined) {
throw Error("Should never come here");
}
// First we call the original implementation of signInUpPOST.
let response = await originalImplementation.signInUpPOST(input);
// Post sign up response, we check if it was successful
if (response.status === "OK") {
let { id, email } = response.user;
// Then we check if the user signed up using email / password or a third party login provider.
if (response.type === "thirdparty") {
// This is the response from the OAuth 2 provider that contains their tokens or user info.
let thirdPartyAuthCodeResponse = response.authCodeResponse;
}
if (input.type === "emailpassword") {
// These are the input form fields values that the user used while signing up / in
let formFields = input.formFields;
}
if (response.createdNewUser) {
// TODO: Post sign up logic
} else {
// TODO: Post sign in logic
}
}
return response;
}
}
}
}
}),
Session.init({ /* ... */ })
]
});
For this, you'll have to override the following APIs in the init
function call, on the backend:
EmailPasswordSignUpPOST
: Sign up with email & passwordEmailPasswordSignInPOST
: Sign in with email & passwordThirdPartySignInUpPOST
: Sign in or up with third party
import (
"github.com/supertokens/supertokens-golang/recipe/emailpassword/epmodels"
"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
"github.com/supertokens/supertokens-golang/recipe/thirdpartyemailpassword"
"github.com/supertokens/supertokens-golang/recipe/thirdpartyemailpassword/tpepmodels"
"github.com/supertokens/supertokens-golang/supertokens"
)
func main() {
supertokens.Init(supertokens.TypeInput{
RecipeList: []supertokens.Recipe{
thirdpartyemailpassword.Init(&tpepmodels.TypeInput{
Override: &tpepmodels.OverrideStruct{
APIs: func(originalImplementation tpepmodels.APIInterface) tpepmodels.APIInterface {
// create a copy of the originalImplementation
originalEmailPasswordSignUpPOST := *originalImplementation.EmailPasswordSignUpPOST
originalEmailPasswordSignInPOST := *originalImplementation.EmailPasswordSignInPOST
originalThirdPartySignInUpPOST := *originalImplementation.ThirdPartySignInUpPOST
// override the email password sign up API
(*originalImplementation.EmailPasswordSignUpPOST) = func(formFields []epmodels.TypeFormField, options epmodels.APIOptions, userContext supertokens.UserContext) (tpepmodels.SignUpPOSTResponse, error) {
// TODO: some pre sign up logic
resp, err := originalEmailPasswordSignUpPOST(formFields, options, userContext)
if err != nil {
return tpepmodels.SignUpPOSTResponse{}, err
}
if resp.OK != nil {
// TODO: some post sign up logic
}
return resp, err
}
// override the email password sign in API
(*originalImplementation.EmailPasswordSignInPOST) = func(formFields []epmodels.TypeFormField, options epmodels.APIOptions, userContext supertokens.UserContext) (tpepmodels.SignInPOSTResponse, error) {
// TODO: some pre sign in logic
resp, err := originalEmailPasswordSignInPOST(formFields, options, userContext)
if err != nil {
return tpepmodels.SignInPOSTResponse{}, err
}
if resp.OK != nil {
// TODO: some post sign in logic
}
return resp, err
}
// override the thirdparty sign in / up API
(*originalImplementation.ThirdPartySignInUpPOST) = func(provider tpmodels.TypeProvider, code string, authCodeResponse interface{}, redirectURI string, options tpmodels.APIOptions, userContext supertokens.UserContext) (tpepmodels.ThirdPartyOutput, error) {
// TODO: some pre sign in / up logic
resp, err := originalThirdPartySignInUpPOST(provider, code, authCodeResponse, redirectURI, options, userContext)
if err != nil {
return tpepmodels.ThirdPartyOutput{}, err
}
if resp.OK != nil {
if resp.OK.CreatedNewUser {
// TODO: some post sign up logic
} else {
// TODO: some post sign in logic
}
}
return resp, err
}
return originalImplementation
},
},
}),
},
})
}
For this, you'll have to override the following APIs in the init
function call, on the backend:
emailpassword_sign_up_post
: Sign up with email & passwordemailpassword_sign_in_post
: Sign in with email & passwordthirdparty_sign_in_up_post
: Sign in or up with third party
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import thirdpartyemailpassword
from supertokens_python.recipe.thirdpartyemailpassword.interfaces import APIInterface, ThirdPartyAPIOptions, EmailPasswordAPIOptions, ThirdPartySignInUpPostOkResult, EmailPasswordSignInPostOkResult, EmailPasswordSignUpPostOkResult
from typing import Union, Dict, Any, List
from supertokens_python.recipe.thirdparty.provider import Provider
from supertokens_python.recipe.emailpassword.types import FormField
def override_thirdpartyemailpassword_apis(original_implementation: APIInterface):
original_thirdparty_sign_in_up_post = original_implementation.thirdparty_sign_in_up_post
original_emailpassword_sign_in_post = original_implementation.emailpassword_sign_in_post
original_emailpassword_sign_up_post = original_implementation.emailpassword_sign_up_post
async def thirdparty_sign_in_up_post(provider: Provider, code: str, redirect_uri: str, client_id: Union[str, None], auth_code_response: Union[Dict[str, Any], None],
api_options: ThirdPartyAPIOptions, user_context: Dict[str, Any]):
# call the default behaviour as show below
result = await original_thirdparty_sign_in_up_post(provider, code, redirect_uri, client_id, auth_code_response, api_options, user_context)
if isinstance(result, ThirdPartySignInUpPostOkResult):
if result.created_new_user:
pass # TODO: some post sign up logic
else:
pass # TODO: some post sign in logic
return result
async def emailpassword_sign_in_post(form_fields: List[FormField],
api_options: EmailPasswordAPIOptions, user_context: Dict[str, Any]):
# call the default behaviour as show below
result = await original_emailpassword_sign_in_post(form_fields, api_options, user_context)
if isinstance(result, EmailPasswordSignInPostOkResult):
pass # TODO: some post sign in logic
return result
async def emailpassword_sign_up_post(form_fields: List[FormField],
api_options: EmailPasswordAPIOptions, user_context: Dict[str, Any]):
# call the default behaviour as show below
result = await original_emailpassword_sign_up_post(form_fields, api_options, user_context)
if isinstance(result, EmailPasswordSignUpPostOkResult):
pass # TODO: some post sign up logic
return result
original_implementation.thirdparty_sign_in_up_post = thirdparty_sign_in_up_post
original_implementation.emailpassword_sign_in_post = emailpassword_sign_in_post
original_implementation.emailpassword_sign_up_post = emailpassword_sign_up_post
return original_implementation
init(
app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
framework='...',
recipe_list=[
thirdpartyemailpassword.init(
override=thirdpartyemailpassword.InputOverrideConfig(
apis=override_thirdpartyemailpassword_apis
)
)
]
)
Using the code above, if createdNewUser
is true
or in emailPasswordSignUpPOST
, you can (for example):
- Add the user's ID and their info to your own database (in addition to it being stored in SuperTokens).
- Send analytics events about a sign up.
- Send a welcome email to the user.