A lightweight, production-ready Node.js REST API server that wraps Supabase Authentication, providing a clean interface for user authentication flows. Features include email/password signup, OTP verification, password reset, Google OAuth, and user management. Includes built-in API tester UI for testing all endpoints.
| Name | Fazla Rabbi |
| Role | Software Developer |
| Portfolio / Website | https://devfazla.com |
| Contact | contact@devfazla.com |
- Backend:
Node.js,Express.js - Auth and Backend:
Supabase(Email/Password, OTP, Google OAuth) - Environment:
dotenv(configuration management) - HTTP & Networking:
node-fetch,cors - Frontend (API Tester):
HTML,CSS,JavaScript(vanilla) - API Testing:
Postman,curl
-
π Complete Authentication Flow
- Email/password signup with OTP verification
- Email/password sign-in
- OTP resend functionality
- Password reset with OTP verification
- Google OAuth integration
-
π€ User Management
- Check if user exists (no admin key required)
- Get user by access token or email (admin)
- User existence validation before password reset
-
π¨ Built-in API Tester
- Interactive web UI for testing all endpoints
- Real-time response display
- No external tools needed
-
π Developer-Friendly
- Comprehensive documentation
- Postman collection included
- curl examples provided
- TypeScript-ready structure
-
π Security
- Environment-based configuration
- CORS enabled
- Input validation
- Error handling
- Node.js 18+ and npm
- Supabase Account (sign up)
- Clone or download this repository
git clone https://github.com/devfazla/Supabase-Auth.git
cd Supabase/Auth- Install dependencies
npm install- Configure environment variables
Copy env.example to .env:
cp env.example .envEdit .env with your Supabase credentials:
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key # Optional, for admin endpoints
PORT=3024 # Optional, defaults to 3024Where to find your keys:
- Go to Supabase Dashboard
- Select your project β Settings β API
- Copy
Project URLβSUPABASE_URL - Copy
anon publickey βSUPABASE_ANON_KEY - Copy
service_rolekey βSUPABASE_SERVICE_ROLE_KEY(keep secret!)
- Start the server
# Development mode (auto-reload on file changes)
npm run dev
# Production mode
npm start- Access the API Tester
Open your browser to: http://localhost:3024
You'll see an interactive UI to test all endpoints!
Base URL: http://localhost:3024 (or your configured PORT)
GET /health
Check if the server is running.
Response:
{
"status": "ok",
"time": "2026-01-29T12:00:00.000Z"
}POST /signUp
Register a new user with email and password. Sends OTP to email if email confirmation is enabled.
Request Body:
{
"email": "user@example.com",
"password": "securePassword123",
"data": { // Optional: user metadata
"display_name": "John Doe"
}
}Response:
{
"status": "ok",
"message": "Signup successful. Please verify OTP sent to email.",
"data": {
"user": { ... },
"session": null // Session created after OTP verification
}
}POST /signUpVerify
Verify the OTP code sent to the user's email after signup.
Request Body:
{
"email": "user@example.com",
"token": "123456",
"type": "signup" // Optional: "signup" (default), "magiclink", "recovery"
}Response:
{
"status": "ok",
"message": "Email verified successfully",
"session": {
"access_token": "...",
"refresh_token": "...",
"user": { ... }
},
"user": { ... }
}POST /resendOtp
Resend a new OTP code to the user's email. Invalidates the previous OTP.
Request Body:
{
"email": "user@example.com"
}Response:
{
"status": "ok",
"message": "OTP resent successfully",
"data": { ... }
}POST /signIn
Authenticate a user with email and password.
Request Body:
{
"email": "user@example.com",
"password": "securePassword123"
}Response:
{
"user": { ... },
"session": {
"access_token": "...",
"refresh_token": "...",
"user": { ... }
}
}GET /gglSignIn
Initiate Google OAuth authentication flow.
Query Parameters:
redirectTo(optional): URL to redirect after authentication
Example:
GET /gglSignIn?redirectTo=https://your-app.com/callback
Response:
{
"url": "https://accounts.google.com/oauth/authorize?..."
}POST /forgtPss
Request a password reset email. Validates user exists before sending email.
Request Body:
{
"email": "user@example.com",
"redirectTo": "https://your-app.com/reset-password" // Optional
}Response:
{
"status": "ok",
"data": { ... }
}Error (if user doesn't exist):
{
"error": "User does not exist"
}POST /resetPssVerify
Verify the OTP token from reset email and set a new password.
Request Body:
{
"email": "user@example.com",
"token": "123456", // OTP from email ({{ .Token }})
"newPassword": "newSecurePassword123"
}Response:
{
"status": "ok",
"message": "Password reset successfully",
"session": {
"access_token": "...",
"refresh_token": "...",
"user": { ... }
},
"user": { ... }
}GET /getUsr
Get user information using an access token from sign-in or OTP verification.
Headers:
Authorization: Bearer <access_token>
Response:
{
"user": {
"id": "...",
"email": "user@example.com",
...
}
}GET /getUsr?email=user@example.com
Get user information by email. Requires SUPABASE_SERVICE_ROLE_KEY.
Query Parameters:
email: User's email address
Response:
[
{
"id": "...",
"email": "user@example.com",
...
}
]POST /usrExst
Check if a user exists by email. No admin key required - uses a clever signup-trick method.
Request Body:
{
"email": "user@example.com"
}Response:
{
"exists": true,
"data": null
}How it works:
Attempts a signup with a random password. If user_metadata and identities are empty/null β user exists. If they have values β new user (doesn't exist).
- Start the server:
npm run dev - Open http://localhost:3024
- Fill in the form fields and click Run on any endpoint
- View responses in real-time below each card
See curl_testing_guide.md for complete curl examples.
Quick examples:
# Health check
curl http://localhost:3024/health
# Sign up
curl -X POST http://localhost:3024/signUp \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"password123"}'
# Sign in
curl -X POST http://localhost:3024/signIn \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"password123"}'Windows PowerShell:
# Use curl.exe and single quotes for JSON
curl.exe -X POST http://localhost:3024/signUp `
-H "Content-Type: application/json" `
-d '{"email":"test@example.com","password":"password123"}'Import supabase_server.postman_collection.json into Postman:
- Open Postman
- Click Import
- Select
supabase_server.postman_collection.json - All endpoints are ready to test!
Supabase/Auth/
βββ server.js # Main server file (all endpoints)
βββ package.json # Dependencies and scripts
βββ env.example # Environment variables template
βββ .env # Your actual env vars (gitignored)
βββ .gitignore # Git ignore rules
βββ README.md # This file
βββ curl_testing_guide.md # curl examples
βββ supabase_server.postman_collection.json # Postman collection
βββ public/
βββ index.html # Built-in API tester UI
| Variable | Required | Description |
|---|---|---|
SUPABASE_URL |
β Yes | Your Supabase project URL |
SUPABASE_ANON_KEY |
β Yes | Supabase anonymous/public key |
SUPABASE_SERVICE_ROLE_KEY |
β No | Service role key (for admin endpoints) |
PORT |
β No | Server port (default: 3024) |
npm run build # Syntax check the server file
npm start # Start server (production)
npm run dev # Start server with auto-reload (development)- Never commit
.env- It's in.gitignorefor a reason! - Service Role Key - Keep
SUPABASE_SERVICE_ROLE_KEYsecret. Only use for admin endpoints. - CORS - Currently enabled for all origins. Restrict in production if needed.
- Password Reset - User existence is validated before sending reset emails to prevent email enumeration.
- Backend API - Use as a middleware/auth layer for your frontend apps
- Mobile Apps - REST API for React Native, Flutter, etc.
- Microservices - Authentication service in a microservices architecture
- Testing - Quick way to test Supabase auth flows
- Prototyping - Fast setup for auth in new projects
- POST
/signUpβ User receives OTP email - POST
/signUpVerifyβ User enters OTP, gets session - GET
/getUsr(with Bearer token) β Get user info
- POST
/forgtPssβ User receives reset email with{{ .Token }} - POST
/resetPssVerifyβ User enters token + new password - User is authenticated with new session
- POST
/usrExstβ Check if email already registered - If
exists: falseβ Proceed with signup - If
exists: trueβ Show "Email already in use"
- Check your
.envfile exists and has correct values - Ensure no extra spaces or quotes around values
- This is intentional! The endpoint validates user exists before sending email
- Use
/usrExstto check if user exists first
- Server has CORS enabled by default
- If issues persist, check browser console for specific error
- Change
PORTin.envto a different port (e.g.,3025) - Or stop the process using port
3024
- Supabase rate-limits email sending (OTP, password reset, etc.) to prevent abuse
- Error message:
"Email rate limit exceeded"or similar - Solution:
- Wait a few minutes before retrying
- Configure email via custom SMTP in Supabase Dashboard β Settings β Auth β SMTP Settings to use your own email provider and bypass rate limits
- Prevention: Avoid rapid successive requests to
/signUp,/resendOtp, or/forgtPsswith the same email - Note: Rate limits vary by Supabase plan (free tier has stricter limits)
ISC
Feel free to submit issues, fork, and create pull requests!
- β Zero dependencies beyond core packages
- β Single file server - Easy to understand and modify
- β Built-in tester - No external tools needed
- β Production-ready - Error handling, validation, CORS
- β Well-documented - README, curl guide, Postman collection
- β Smart user check - No admin key needed for existence check
Made with β€οΈ for the Supabase community
