This is a demonstration of integrating SuperTokens authentication with the Effect framework in a Node.js environment. The server showcases passwordless authentication, protected routes, and Effect's middleware system.
The server is built using several key components:
- Effect Framework: Provides the core server functionality and type-safe error handling, routing and middleware
- SuperTokens: Handles authentication with passwordless login
- React: Frontend web application
- Inbucket: Local SMTP server for testing emails
-
Server Initialization:
- Environment variables are loaded through Effect's Config system
- SuperTokens is initialized with passwordless authentication
- CORS middleware is configured to handle SuperTokens headers
- API routes are defined using Effect's HttpApiBuilder
-
Authentication Flow:
- User enters any email address for passwordless login
- Magic link code is sent to local SMTP server (viewable at localhost:9000)
- User enters the code to authenticate
- Protected routes check session status
- User metadata can be accessed for authenticated users
yarn install
- Copy the
.env.example
file to.env
in the server app - Copy the
.env.example
file to.env
in the web app - Copy the
.env.example
file to.env
for the SuperTokens Docker
Install Docker Desktop or alternatives like OrbStack and start the required services:
Run the following commands to start the containers:
docker compose -f docker/email/docker-compose.yaml up -d
docker compose -f docker/supertokens/docker-compose.yaml up -d
[!NOTE] For stopping the containers:
docker compose -f docker/email/docker-compose.yaml down docker compose -f docker/supertokens/docker-compose.yaml down
Start the reverse proxy, server, and web applications in separate terminal windows:
# Terminal 1 - Start Caddy reverse proxy (handles HTTPS and routing)
caddy run --watch
# Terminal 2 - Start the server (runs on localhost:4040)
yarn workspace @demo/server start
# Terminal 3 - Start the web app (runs on localhost:3000)
yarn workspace @demo/web start
The applications will be available at:
- Web app: https://localhost
- API: https://localhost/api
- Email: http://localhost:9000
Note
Using Caddy as a reverse proxy provides:
- Single domain for both web and API (https://localhost)
- Automatic HTTPS certificates
- Proper same-origin cookie handling for authentication
- Production-like environment locally
Make sure to create a Caddyfile
in your project root.
- Open
http://localhost:3000
in your browser - Enter any email address in the login form
- Open
http://localhost:9000
in a new tab to access the Inbucket email interface - Find your email and copy the magic link code
- Enter the code in the verification form
- You'll be logged in and can access protected routes
You can test the authentication endpoints using Postman or similar API testing tools. Below are the key endpoints and how to test them:
- The server runs on
localhost:4040
by default - Use cookie-based sessions by adding the
st-auth-mode: cookie
header - Postman automatically manages cookies, so you don't need to manually handle them
- Method: POST
- URL:
http://localhost:4040/auth/signinup/code
- Body (raw JSON):
{
"email": "[email protected]"
}
- This will generate a magic link code (check your console logs in development)
- Method: POST
- URL:
http://localhost:4040/auth/signinup/code/consume
- Headers:
st-auth-mode
:cookie
- Body (raw JSON):
{
"preAuthSessionId": "[ID from previous response]",
"deviceId": "[Device ID from previous response]",
"userInputCode": "[Code from magic link/email]"
}
On success, Postman will automatically store the session cookies (sAccessToken
and sRefreshToken
).
For endpoints requiring authentication:
- Postman will automatically include the session cookies
- Example protected route test:
- Method: GET
- URL:
http://localhost:4040/api/protected
- The cookies from your sign-in will be automatically included
If your access token expires:
- Method: POST
- URL:
http://localhost:4040/auth/session/refresh
- Postman will automatically include the refresh token cookie
- New session tokens will be set in the cookies automatically
To end a session:
- Method: POST
- URL:
http://localhost:4040/auth/signout
- This will clear the session cookies
- 401 Unauthorized: Your session might have expired. Use the refresh endpoint to get new tokens.
- CORS Errors: Make sure your Postman requests include any required CORS headers configured in your server.
- Cookie Issues: Verify that you've included the
st-auth-mode: cookie
header during sign-in.
- Supertokens Passwordless (magic link + only email) backend setup: https://supertokens.com/docs/passwordless/quickstart/backend-setup)
- Supertokens getting user id and user metadata: https://supertokens.com/docs/passwordless/common-customizations/get-user-info#fetching-information-using-the-users-id
- Effect documentation: https://effect.website/
- [Server] Load Supertokens' verify session (middleware.ts)
- [Server] Load Supertokens' UserMetadata singleton (middleware.ts)
- [Server] Initialize supertokens.ts when starting server
- [Server] Load environment variables in places using
Config.string
(like in supertokens.ts and cors.ts) - [Server] Start server in index.ts
MIT