SuperTokens ReactJS Auth SDK
repository·master·Indexed 43 days ago
https://github.com/supertokens/supertokens-auth-reactA client-side library (version 0.51.3) that enables React applications to integrate SuperTokens authentication services, providing ready-to-use login functionality and session management.
What's inside SuperTokens
- The SuperTokens ReactJS Auth SDK is a client-side library designed to provide seamless login and authentication functionality for React applications using the SuperTokens backend. It handles the complexities of session management, authentication flows, and communication with the SuperTokens service.
Integrate SuperTokens with Supabase
masterThis example demonstrates how to use SuperTokens for EmailPassword and Social Login authentication in a Next.js application while integrating with Supabase to manage user-specific data.
Core Workflow
- Authentication: Users authenticate via SuperTokens (Email/Password or Social Login).
- Data Mapping: A table is created in Supabase that maps a user's email (retrieved from SuperTokens) to their specific
userId. - Secure Querying: Supabase Row Level Security (RLS) policies are used to ensure that an authenticated user can only retrieve their own information from the mapping table.
Project structure of the EmailPassword Vercel demo
masterThe demo application follows this structure to integrate a React frontend with a Node.js Express backend on Vercel:
- Frontend: Located in the
srcfolder. - Backend API: An Express application located in
api/index.js. - Vercel Configuration: The
vercel.jsonfile is used to instruct Vercel to proxy all requests starting with/apito the backend server (api/index.js).
- Frontend: Located in the
How CLI browser-based login works with Passwordless
masterThis pattern implements a sign-in flow for CLI clients where the authentication happens in a web browser. It leverages the SuperTokens Passwordless recipe and a magic link flow.
The Flow
- Magic Link Generation: The CLI calls the backend
getmagiclinkGET API. The backend returns a magic link containing two tokens:preAuthSessionIdandlinkCode. - Token Roles:
linkCode: A one-time use, secret token consumed via theconsumetokenPOST API.preAuthSessionId: A non-secret token used to associate metadata (like the user's identity) with the login process.
- Frontend Handling:
- If the user is already logged in to the browser, the frontend extracts the tokens and calls the
consumetokenAPI immediately. - If not logged in, the frontend saves the tokens in
localStorage, redirects the user to the login flow, and then sends the tokens to theconsumetokenAPI after successful login.
- If the user is already logged in to the browser, the frontend extracts the tokens and calls the
- Backend Consumption:
- The
consumetokenAPI verifies the session, then usesPasswordless.consumeCodeto validate thelinkCode. - Upon success, the backend maps the
preAuthSessionIdto theuserId. In this demo, the UserMetadata recipe is used for this mapping (though a database with TTL is recommended for production).
- The
- CLI Completion:
- The CLI polls the
/waitforloginAPI using thepreAuthSessionId. - Once the mapping is found, the backend generates a long-lived JWT (via the JWT recipe) and returns it to the CLI, completing the login.
- The CLI polls the
- Magic Link Generation: The CLI calls the backend
Implement email verification followed by password setting
masterThis pattern allows you to verify a user's email address before they establish a permanent password.
The Workflow:
- Initial Sign-up: When a user signs up via email, assign a fake, random, and unguessable password to the user's account. This allows the system to create a session and proceed with the standard email verification flow.
- Email Verification: The user completes the standard email verification process.
- Password Setup: Once the email is verified, present a UI to the user to set their actual password.
- Password Update: Call an API to update the user's account, replacing the fake password with the one they just provided.
Handle Electron-specific authentication constraints
masterWhen using SuperTokens with Electron, you must account for how Electron handles cookies and the Window API. This demo implements the following patterns to ensure compatibility:
- Custom Handlers: Pass custom cookie and window handlers when calling
SuperTokens.initinsrc/renderer.tsx. The implementation logic for these handlers is located insrc/cookieHandler.tsandsrc/windowHandler.ts. - Routing: The app uses
HashRouterfromreact-router-dombecause social providers and file protocols used by Electron do not support standard browser routing. - Deeplinking: The app uses a registered protocol (default:
supertokens-demo) to handle Magic Link redirects. You can change this by updatingdeeplinkProtocolin bothsrc/renderer.tsxandapi-server/index.js. - Social Login Redirection: Since social providers do not support
HashRouteror file protocol URLs, the app uses theapiDomainfor redirect URLs. The backend (api-server/index.js) provides two specific routes to bridge this:/auth/callback/:providerIdand/auth/verify, which redirect back to the app using the registered protocol. - Magic Link Verification: For production builds where Electron uses the
file://protocol, magic links are modified to use theapiDomain. The/auth/verifyroute handles the internal redirection back to the app via the registered protocol.
- Custom Handlers: Pass custom cookie and window handlers when calling
Substitute frontend cookies with localStorage for header-based auth
masterWhen using header-based authentication, you can redirect the storage of session tokens from browser cookies to
localStorageby providing a customcookieHandlerduring thesupertokens.initconfiguration.To implement this, you must create a handler that implements the functions for getting and setting cookies, but directs those operations to
localStorageinstead. In this pattern, tokens are typically stored under a specific key (e.g.,frontendCookies) within the browser'slocalStorage.// Conceptual implementation pattern // The custom handler is passed to supertokens.init supertokens.init({ // ... other config cookieHandler: getCookieHandler(), });Best practices for OTP storage in Email Verification
masterWhen implementing an OTP-to-token mapping for email verification, consider the following production requirements:
- Persistence: The demo implementation uses in-memory storage for the OTP-to-token mapping. For production, store this mapping in a database to ensure persistence across server restarts.
- Cleanup: Unused OTPs can accumulate in your storage. Implement a cronjob or a background process to periodically remove expired or unused OTP mappings to prevent memory leaks or database bloat.
How Account Linking works in SuperTokens
masterAccount linking allows a single user to have multiple login methods (e.g., Email/Password and Google). This demo implements two types of linking:
Automatic Account Linking
Enabled on the backend by initializing the recipe with a
shouldDoAutomaticAccountLinkingimplementation. When a user logs in via a third-party provider, SuperTokens checks if the account should be automatically linked to an existing user.Manual Account Linking
For more control, you can implement manual linking via custom API endpoints. In this demo:
- A custom
/linkpage is used to manage login methods. - The frontend calls custom backend endpoints like
/addPasswordor/addPhoneNumberto associate new credentials with the currently logged-in user. - Third-party account linking is handled by the built-in sign-in/up endpoints.
- A custom
Implement Okta Thirdparty Login with PKCE Flow
masterThis pattern demonstrates how to implement a custom thirdparty provider using Okta with the PKCE (Proof Key for Code Exchange) flow. It involves two main architectural requirements:
Custom Thirdparty Provider Support:
- Implementing Code Challenge and Verifier logic.
- Passing state from the frontend to the backend APIs to maintain the authentication context.
Multi-tenancy Support:
- Accepting a
tenantIdin the frontend. - Passing the
tenantIdto backend APIs. - Using the
tenantIdon the backend to simulate or route to different User Pools.
- Accepting a
Implement sign-up without automatic session creation
masterThis demo implements a pattern where signing up (via Social or Email/Password) does not automatically log the user in, but instead prompts them to sign in again. This is achieved through two mechanisms:
API Override: The default sign-up behavior is modified using the API override feature. The custom logic is located in:
api-server/customSignInUpPOST.js(for social login)api-server/customSignUpPOST.js(for email/password login)
Frontend UI Feedback: To inform the user they need to log in manually after a successful sign-up:
- Event Handling: In
src/App.js, theonHandleEventfunction is used to set a flag inlocalStoragewhen a sign-up event is triggered. - Component Override: The react component override feature is used to override the
ThirdPartyEmailPasswordHeadercomponent. A custom component,SignInMessage(defined insrc/App.js), checks thelocalStorageflag and displays a message to the user.
- Event Handling: In
Implement EmailPassword with multiple emails per user
masterThis pattern allows users to associate multiple email addresses with a single account and use any of them to log in. It also ensures that the email verification flow covers all associated emails.
Implementation Logic
- Data Storage: You must manage a mapping in your own database that links a primary email ID (the one used during initial signup) to a list of secondary email IDs.
- Backend Overrides:
- Login/Authentication: Override the
EmailPasswordrecipe functions on the backend. For any function accepting an email, look up the primary email associated with the input email in your map, then call the original SuperTokens implementation using that primary email. - Email Verification: Override email verification functions to loop through all emails associated with the user (not just the one provided) to ensure all secondary emails are verified if they are unverified.
- Login/Authentication: Override the
- Frontend: The frontend uses standard SuperTokens SDK calls, but the backend logic handles the translation from secondary email to primary email automatically.