Skip to content
Esc
navigateopen⌘Jpreview
Dashboard
On this page

Set Up Passwordless Authentication

Integrate email or SMS passwordless authentication with magic links, OTPs, or both using prebuilt or custom UI.

Implement passwordless authentication with the right contact and flow options.

Overview

This page shows you how to add the Passwordless recipe to your project. The tutorial creates a login flow, rendered by either the Prebuilt UI components or by your own Custom UI.

Terminology

Before going into the actual steps lets first talk about two terms that influence how you configure the Passwordless recipe.

  • Contact Method: This defines how the user receives the credentials from your app. You can choose between email, phone number or both (the user has to choose one during the login flow).
  • Flow Type: This is the credential type used for authentication. You can choose Magic Link, OTP (One-Time Password), or both. The combined flow sends both credentials and the user can complete authentication with either one.

Steps

UI type

1. Initialize the frontend SDK

1.1 Add the Passwordless recipe in your main configuration file.

Add the Passwordless recipe in your AuthComponent.

Add the Passwordless recipe in your AuthView file.

import React from "react";

import SuperTokens, { SuperTokensWrapper } from "supertokens-auth-react";
import Passwordless from "supertokens-auth-react/recipe/passwordless";
import Session from "supertokens-auth-react/recipe/session";

SuperTokens.init({
  appInfo: {
    // learn more about this on https://supertokens.com/docs/references/frontend-sdks/reference#sdk-configuration
    appName: "<YOUR_APP_NAME>",
    apiDomain: "<YOUR_API_DOMAIN>",
    websiteDomain: "<YOUR_WEBSITE_DOMAIN>",
    apiBasePath: "/auth",
    websiteBasePath: "/auth",
  },
  recipeList: [
    Passwordless.init({
      contactMethod: "EMAIL",
    }),
    Session.init(),
  ],
});
import { Component, OnDestroy, AfterViewInit, Renderer2, Inject } from "@angular/core";
import { DOCUMENT } from "@angular/common";

@Component({
  selector: "app-auth",
  template: '<div id="supertokensui"></div>',
})
export class AuthComponent implements OnDestroy, AfterViewInit {
  constructor(
    private renderer: Renderer2,
    @Inject(DOCUMENT) private document: Document,
  ) {}

  ngAfterViewInit() {
    this.loadScript("https://cdn.jsdelivr.net/gh/supertokens/prebuiltui@vX.Y.Z/build/static/js/main.test.js");
  }

  ngOnDestroy() {
    // Remove the script when the component is destroyed
    const script = this.document.getElementById("supertokens-script");
    if (script) {
      script.remove();
    }
  }

  private loadScript(src: string) {
    const script = this.renderer.createElement("script");
    script.type = "text/javascript";
    script.src = src;
    script.id = "supertokens-script";
    script.onload = () => {
      supertokensUIInit({
        appInfo: {
          // learn more about this on https://supertokens.com/docs/references/frontend-sdks/reference#sdk-configuration
          appName: "<YOUR_APP_NAME>",
          apiDomain: "<YOUR_API_DOMAIN>",
          websiteDomain: "<YOUR_WEBSITE_DOMAIN>",
          apiBasePath: "/auth",
          websiteBasePath: "/auth",
        },
        recipeList: [
          supertokensUIPasswordless.init({
            contactMethod: "EMAIL",
          }),
          supertokensUISession.init(),
        ],
      });
    };
    this.renderer.appendChild(this.document.body, script);
  }
}
<script lang="ts">
  import { defineComponent, onMounted, onUnmounted } from "vue";
  export default defineComponent({
    setup() {
      const loadScript = (src: string) => {
        const script = document.createElement("script");
        script.type = "text/javascript";
        script.src = src;
        script.id = "supertokens-script";
        script.onload = () => {
          supertokensUIInit({
            appInfo: {
              // learn more about this on https://supertokens.com/docs/references/frontend-sdks/reference#sdk-configuration
              appName: "<YOUR_APP_NAME>",
              apiDomain: "<YOUR_API_DOMAIN>",
              websiteDomain: "<YOUR_WEBSITE_DOMAIN>",
              apiBasePath: "/auth",
              websiteBasePath: "/auth",
            },
            recipeList: [
              supertokensUIPasswordless.init({
                contactMethod: "EMAIL",
              }),
              supertokensUISession.init(),
            ],
          });
        };
        document.body.appendChild(script);
      };

      onMounted(() => {
        loadScript("https://cdn.jsdelivr.net/gh/supertokens/prebuiltui@vX.Y.Z/build/static/js/main.test.js");
      });

      onUnmounted(() => {
        const script = document.getElementById("supertokens-script");
        if (script) {
          script.remove();
        }
      });
    },
  });
</script>

<template>
  <div id="supertokensui" />
</template>

1.2 Include the pre-built UI components in your application.

To render the Pre-Built UI inside your application, you need to specify which routes show the authentication components. The React SDK uses React Router under the hood to achieve this. Based on whether you already use this package or not in your project, there are two different ways of configuring the routes.

2. Initialize the backend SDK

You need to initialize the Backend SDK alongside the code that starts your server. The init call includes configuration details for your app. It specifies how the backend connects to the SuperTokens Core, as well as the Recipes used in your setup.

For the Passwordless recipe, you also need to specify the flowType and contactMethod. Click one of the options from the next form and the code snippet updates.

import supertokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";
import Passwordless from "supertokens-node/recipe/passwordless";

supertokens.init({
  // Replace this with the framework you are using
  framework: "express",
  supertokens: {
    // We use try.supertokens for demo purposes.
    // At the end of the tutorial we will show you how to create
    // your own SuperTokens core instance and then update your config.
    connectionURI: "https://try.supertokens.io",
    // apiKey: <YOUR_API_KEY>
  },
  appInfo: {
    // learn more about this on https://supertokens.com/docs/references/backend-sdks/reference#sdk-configuration
    appName: "<YOUR_APP_NAME>",
    apiDomain: "<YOUR_API_DOMAIN>",
    websiteDomain: "<YOUR_WEBSITE_DOMAIN>",
    apiBasePath: "/auth",
    websiteBasePath: "/auth",
  },
  recipeList: [
    Passwordless.init({
      flowType: "MAGIC_LINK",
      contactMethod: "EMAIL",
    }),
    Session.init(),
  ],
});
from supertokens_python import init, InputAppInfo, SupertokensConfig
from supertokens_python.recipe import passwordless, session
from supertokens_python.recipe.passwordless import ContactEmailOnlyConfig

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(
        # We use try.supertokens for demo purposes.
        # At the end of the tutorial we will show you how to create
        # your own SuperTokens core instance and then update your config.
        connection_uri="https://try.supertokens.io",
        # api_key: <YOUR_API_KEY>
    ),
    framework='fastapi',
    recipe_list=[
        session.init(), # initializes session features
        passwordless.init(
            flow_type="MAGIC_LINK",
            contact_config=ContactEmailOnlyConfig()
        )
    ],
    mode='asgi' # use wsgi if you are running using gunicorn
)
import (
	"github.com/supertokens/supertokens-golang/recipe/session"
	"github.com/supertokens/supertokens-golang/recipe/passwordless"
	"github.com/supertokens/supertokens-golang/recipe/passwordless/plessmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
  apiBasePath := "/auth"
  websiteBasePath := "/auth"
  err := supertokens.Init(supertokens.TypeInput{
    Supertokens: &supertokens.ConnectionInfo{
          // We use try.supertokens for demo purposes.
          // At the end of the tutorial we will show you how to create
          // your own SuperTokens core instance and then update your config.
          ConnectionURI: "https://try.supertokens.io",
          // APIKey: <YOUR_API_KEY>
    },
    AppInfo: supertokens.AppInfo{
            AppName: "<YOUR_APP_NAME>",
            APIDomain: "<YOUR_API_DOMAIN>",
            WebsiteDomain: "<YOUR_WEBSITE_DOMAIN>",
            APIBasePath: &apiBasePath,
            WebsiteBasePath: &websiteBasePath,
    },
    RecipeList: []supertokens.Recipe{
      passwordless.Init(plessmodels.TypeInput{
                FlowType: "MAGIC_LINK",
                ContactMethodEmail: plessmodels.ContactMethodEmailConfig{Enabled: true},
            }),
      session.Init(nil), // initializes session features
    },
  })

	if err != nil {
		panic(err.Error())
	}
}

Next steps

Having completed the main setup, you can explore more advanced topics related to the Passwordless recipe.

API reference

API schema and response details