Customization - SuperTokens Docs

Customization

Overview

Like the other SuperTokens authentication recipes, you can customize the WebAuthn flow through different configuration options and overrides. The following page describes the options that you can change and the different scenarios enabled through customization.

Backend recipe configuration

Node.js

import supertokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";
import WebAuthn from "supertokens-node/recipe/webauthn";

supertokens.init({
  framework: "express",
  supertokens: {
    connectionURI: "https://try.supertokens.com",
  },
  appInfo: {
    appName: "<YOUR_APP_NAME>",
    apiDomain: "<YOUR_API_DOMAIN>",
    websiteDomain: "<YOUR_WEBSITE_DOMAIN>",
    apiBasePath: "/auth",
    websiteBasePath: "/auth",
  },
  recipeList: [
    WebAuthn.init({
      getOrigin: async () => {
        return "https://example.com";
      },
      getRelyingPartyId: async () => {
        return "example.com";
      },
      getRelyingPartyName: async () => {
        return "example";
      },
    }),
    Session.init(),
  ],
});

Go

import (
    "net/http"
    "github.com/supertokens/supertokens-golang/recipe/session"
    "github.com/supertokens/supertokens-golang/recipe/webauthn"
    "github.com/supertokens/supertokens-golang/recipe/webauthn/webauthnmodels"
    "github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
    apiBasePath := "/auth"
    websiteBasePath := "/auth"
    err := supertokens.Init(supertokens.TypeInput{
        Supertokens: &supertokens.ConnectionInfo{ConnectionURI: "https://try.supertokens.com"},
        AppInfo: supertokens.AppInfo{
            AppName: "<YOUR_APP_NAME>",
            APIDomain: "<YOUR_API_DOMAIN>",
            WebsiteDomain: "<YOUR_WEBSITE_DOMAIN>",
            APIBasePath: &apiBasePath,
            WebsiteBasePath: &websiteBasePath,
        },
        RecipeList: []supertokens.Recipe{
            webauthn.Init(&webauthnmodels.TypeInput{
                GetOrigin: func(tenantID string, req *http.Request, userContext supertokens.UserContext) (string, error) {
                    return "https://example.com", nil
                },
                GetRelyingPartyId: func(tenantID string, req *http.Request, userContext supertokens.UserContext) (string, error) {
                    return "example.com", nil
                },
                GetRelyingPartyName: func(tenantID string, userContext supertokens.UserContext) (string, error) {
                    return "example", nil
                },
            }),
            session.Init(nil),
        },
    })
    if err != nil {
        panic(err)
    }
}

Python

from typing import Optional
from supertokens_python import InputAppInfo, SupertokensConfig, init
from supertokens_python.framework import BaseRequest
from supertokens_python.recipe import session, webauthn
from supertokens_python.recipe.webauthn import WebauthnConfig
from supertokens_python.types.base import UserContext

async def get_origin(*, tenant_id: str, request: Optional[BaseRequest], user_context: UserContext):
    return "https://example.com"

async def get_relying_party_id(*, tenant_id: str, request: Optional[BaseRequest], user_context: UserContext):
    return "example.com"

async def get_relying_party_name(*, tenant_id: str, user_context: UserContext):
    return "example"

init(
    app_info=InputAppInfo(
        app_name="<YOUR_APP_NAME>",
        api_domain="<YOUR_API_DOMAIN>",
        website_domain="<YOUR_WEBSITE_DOMAIN>",
        api_base_path="/auth",
        website_base_path="/auth"
    ),
    supertokens_config=SupertokensConfig(
        connection_uri="https://try.supertokens.com",
    ),
    framework='flask',
    recipe_list=[
        webauthn.init(
            config=WebauthnConfig(
                get_origin=get_origin,
                get_relying_party_id=get_relying_party_id,
                get_relying_party_name=get_relying_party_name,
            )
        ),
        session.init()
    ]
)

Node.js

The backend recipe accepts the following properties during initialization:

Option Description Default
getRelyingPartyId Sets the domain name associated with the WebAuthn credentials. This helps ensure that only your domain uses the credentials. Hostname of appInfo.apiDomain
getRelyingPartyName Sets a human-readable name for your application. The name appears to users during the WebAuthn registration process. The appName value that you have set in appConfig
getOrigin Configures the frontend origin that WebAuthn credentials bind to. appInfo.getOrigin(...), normally the configured website origin
emailDelivery Configures how the system builds and sends account-recovery emails. Default email service
validateEmailAddress Adds custom validation logic for email addresses. Basic email format validation

All the properties are optional.

Credential generation

The client generates the credentials based on the options provided by the backend SDK. The frontend SDK uses navigator.credentials.create() to start the registration ceremony.

To change the options used to generate credentials, you need to override the registerOptions function.

Credential validation

When a user attempts to sign in, the authenticator uses their credential to sign an assertion on the client. The frontend SDK uses navigator.credentials.get() to start the authentication ceremony. The server generates the options for signing the challenge through the backend SDK, and then sends them to the client. To change those, you need to override the signInOptions function.