コンテンツにスキップ

SuperTokens Cheat Sheet

Overview

SuperTokens is an open-source authentication solution that provides pre-built auth recipes for email/password, passwordless, social login, and multi-factor authentication. It can be self-hosted or used as a managed service, giving developers full control over their authentication infrastructure while reducing implementation complexity.

SuperTokens uses a unique architecture with a Core service (Java-based) that handles token management and session storage, and frontend/backend SDKs that integrate into your application. It supports React, Angular, Vue, Next.js, Node.js, Python, and Go, with automatic session management using rotating refresh tokens and anti-CSRF protection.

Installation

# Node.js backend SDK
npm install supertokens-node

# React frontend SDK
npm install supertokens-auth-react

# React Native
npm install supertokens-react-native

# Python backend SDK
pip install supertokens-python

# Go backend SDK
go get github.com/supertokens/supertokens-golang

# SuperTokens Core (Docker)
docker run -d \
  --name supertokens \
  -p 3567:3567 \
  registry.supertokens.io/supertokens/supertokens-postgresql

Backend Setup (Node.js)

const supertokens = require("supertokens-node");
const Session = require("supertokens-node/recipe/session");
const EmailPassword = require("supertokens-node/recipe/emailpassword");
const ThirdParty = require("supertokens-node/recipe/thirdparty");
const Dashboard = require("supertokens-node/recipe/dashboard");

supertokens.init({
  framework: "express",
  supertokens: {
    connectionURI: "https://try.supertokens.com",
    // For self-hosted:
    // connectionURI: "http://localhost:3567",
    // apiKey: "your-api-key",
  },
  appInfo: {
    appName: "My App",
    apiDomain: "http://localhost:3001",
    websiteDomain: "http://localhost:3000",
    apiBasePath: "/auth",
    websiteBasePath: "/auth",
  },
  recipeList: [
    EmailPassword.init(),
    ThirdParty.init({
      signInAndUpFeature: {
        providers: [
          ThirdParty.Google({
            clientId: process.env.GOOGLE_CLIENT_ID,
            clientSecret: process.env.GOOGLE_CLIENT_SECRET,
          }),
          ThirdParty.Github({
            clientId: process.env.GITHUB_CLIENT_ID,
            clientSecret: process.env.GITHUB_CLIENT_SECRET,
          }),
        ],
      },
    }),
    Session.init(),
    Dashboard.init(),
  ],
});

// Express middleware
const { middleware, errorHandler } = require("supertokens-node/framework/express");
app.use(middleware());
// ... routes
app.use(errorHandler());

Frontend Setup (React)

import SuperTokens from "supertokens-auth-react";
import EmailPassword from "supertokens-auth-react/recipe/emailpassword";
import ThirdParty from "supertokens-auth-react/recipe/thirdparty";
import Session from "supertokens-auth-react/recipe/session";

SuperTokens.init({
  appInfo: {
    appName: "My App",
    apiDomain: "http://localhost:3001",
    websiteDomain: "http://localhost:3000",
    apiBasePath: "/auth",
    websiteBasePath: "/auth",
  },
  recipeList: [
    EmailPassword.init(),
    ThirdParty.init(),
    Session.init(),
  ],
});

// Wrap your app
import { SuperTokensWrapper } from "supertokens-auth-react";

function App() {
  return (
    <SuperTokensWrapper>
      <Routes />
    </SuperTokensWrapper>
  );
}

Route Protection

// Backend - protect API routes
const { verifySession } = require("supertokens-node/recipe/session/framework/express");

app.get("/api/user", verifySession(), async (req, res) => {
  const userId = req.session.getUserId();
  const accessTokenPayload = req.session.getAccessTokenPayload();
  res.json({ userId, payload: accessTokenPayload });
});

// Require specific claims
const { UserRoleClaim } = require("supertokens-node/recipe/userroles");

app.get("/api/admin", verifySession({
  overrideGlobalClaimValidators: async (globalValidators) => [
    ...globalValidators,
    UserRoleClaim.validators.includes("admin"),
  ],
}), async (req, res) => {
  res.json({ message: "Admin access granted" });
});
// Frontend - protected routes
import { SessionAuth } from "supertokens-auth-react/recipe/session";

function ProtectedPage() {
  return (
    <SessionAuth>
      <Dashboard />
    </SessionAuth>
  );
}

Session Management

// Backend session operations
const Session = require("supertokens-node/recipe/session");

// Create session with custom payload
app.post("/login", async (req, res) => {
  const session = await Session.createNewSession(req, res, "public", userId, {
    role: "admin",
    plan: "premium",
  });
  res.json({ status: "OK" });
});

// Update session claims
app.post("/upgrade", verifySession(), async (req, res) => {
  await req.session.mergeIntoAccessTokenPayload({
    plan: "enterprise",
  });
  res.json({ status: "OK" });
});

// Revoke session
app.post("/logout", verifySession(), async (req, res) => {
  await req.session.revokeSession();
  res.json({ status: "OK" });
});

// Revoke all sessions for a user
await Session.revokeAllSessionsForUser(userId);
// Frontend session access
import Session from "supertokens-auth-react/recipe/session";
import { useSessionContext } from "supertokens-auth-react/recipe/session";

function Profile() {
  const session = useSessionContext();

  if (session.loading) return <div>Loading...</div>;
  if (!session.doesSessionExist) return <div>Not logged in</div>;

  return (
    <div>
      <p>User ID: {session.userId}</p>
      <p>Role: {session.accessTokenPayload.role}</p>
    </div>
  );
}

User Roles and Permissions

const UserRoles = require("supertokens-node/recipe/userroles");

// Add to recipe list
UserRoles.init();

// Create role
await UserRoles.createNewRoleOrAddPermissions("admin", [
  "read:users", "write:users", "delete:users",
]);

// Assign role to user
await UserRoles.addRoleToUser("public", userId, "admin");

// Get user roles
const { roles } = await UserRoles.getRolesForUser("public", userId);

// Check permissions
const { permissions } = await UserRoles.getPermissionsForRole("admin");

Advanced Usage

Custom Email/Password Validation

EmailPassword.init({
  signUpFeature: {
    formFields: [
      {
        id: "email",
        validate: async (value) => {
          if (!value.endsWith("@company.com")) {
            return "Only company emails allowed";
          }
          return undefined;
        },
      },
      {
        id: "password",
        validate: async (value) => {
          if (value.length < 12) return "Password must be at least 12 characters";
          return undefined;
        },
      },
      {
        id: "name",
        optional: false,
      },
    ],
  },
  override: {
    apis: (originalImplementation) => ({
      ...originalImplementation,
      signUpPOST: async (input) => {
        const response = await originalImplementation.signUpPOST(input);
        if (response.status === "OK") {
          // Post-signup actions (send welcome email, etc.)
          await sendWelcomeEmail(response.user.email);
        }
        return response;
      },
    }),
  },
});

Multi-Factor Authentication

const MultiFactorAuth = require("supertokens-node/recipe/multifactorauth");
const TOTP = require("supertokens-node/recipe/totp");

// Add to recipe list
MultiFactorAuth.init({
  firstFactors: ["emailpassword", "thirdparty"],
});
TOTP.init();

Self-Hosted with PostgreSQL

docker run -d \
  --name supertokens \
  -p 3567:3567 \
  -e POSTGRESQL_CONNECTION_URI="postgresql://user:pass@host:5432/supertokens" \
  registry.supertokens.io/supertokens/supertokens-postgresql

Configuration

# Environment variables
SUPERTOKENS_CONNECTION_URI="http://localhost:3567"
SUPERTOKENS_API_KEY="your-api-key"
GOOGLE_CLIENT_ID="your-google-client-id"
GOOGLE_CLIENT_SECRET="your-google-client-secret"
GITHUB_CLIENT_ID="your-github-client-id"
GITHUB_CLIENT_SECRET="your-github-client-secret"

Troubleshooting

IssueSolution
CORS errorsEnsure apiDomain and websiteDomain match; add CORS middleware before SuperTokens
Session not persistingCheck cookie domain; ensure frontend and backend share the same top-level domain
Core connection refusedVerify SuperTokens Core is running; check connectionURI
Social login redirect failsVerify OAuth callback URLs match your apiDomain + apiBasePath
Token refresh failingEnsure Session.init() interceptor is added to frontend HTTP client
Dashboard not loadingAdd Dashboard.init() to recipe list; access at apiDomain/auth/dashboard
Role claims missingEnsure UserRoles.init() is in recipe list and roles are assigned
Migration issuesUse the user migration APIs to import users from other providers