# WeWeb User Authentication: Supabase Auth, Auth0, Xano, and Social Login

- Tool: WeWeb
- Difficulty: Intermediate
- Time required: 45–75 min
- Compatibility: WeWeb Free plan and above (auth plugin required)
- Last updated: March 2026

## TL;DR

WeWeb supports four production-ready auth providers: Supabase Auth (recommended for most projects), Auth0 (enterprise), Xano Auth, and Token-based Auth (custom). Set up login and signup flows by adding the auth plugin, configuring redirect pages, and creating On submit workflows that call login/signup actions. Social login (Google, GitHub) requires enabling OAuth providers in your auth backend first.

## Setting Up User Authentication in WeWeb

Authentication is one of the most common requirements for apps built in WeWeb. The platform supports multiple auth providers through its plugin system — Supabase Auth for most projects, Auth0 for enterprise with advanced requirements, Xano Auth for Xano backend users, and Token-based Auth for completely custom systems. This tutorial focuses on the Supabase Auth path (the most common choice) while covering the decision framework for choosing a provider. You will set up the full auth flow: user signup with email confirmation, login, social OAuth (Google), password reset, and logout — plus how to access the current user's data in your app's bindings and workflows.

## Before you start

- A WeWeb project with the Supabase backend plugin already connected (or ready to connect)
- A Supabase project at supabase.com with email auth enabled
- Basic familiarity with WeWeb workflows and the Plugins panel

## Step-by-step guide

### 1. Choose your authentication provider

WeWeb offers four auth options, each with different trade-offs. Supabase Auth: the recommended default for most WeWeb projects. Natively integrates with the Supabase data source plugin — the auth token is automatically forwarded to all Supabase database operations. Supports email/password, magic links, phone OTP, and 20+ social OAuth providers. Free tier allows 50,000 monthly active users. Auth0: recommended for enterprise projects requiring advanced identity features — MFA, custom rules, enterprise SSO (SAML), extensive audit logs, or compliance requirements (SOC 2, HIPAA). Auth0 free tier supports 7,000 active users. The Auth0 WeWeb plugin auto-creates Machine-to-Machine and Single Page Application apps in Auth0. Xano Auth: use only if your backend is already Xano. The token is automatically forwarded to all Xano API calls. Requires 3 standard auth endpoints in Xano (signup, login, me). WeWeb Auth: explicitly NOT recommended for production — WeWeb's documentation states this is proof-of-concept only, not suitable for large user bases. Token-based Auth: for custom auth APIs not covered by the above options.

**Expected result:** You have selected an auth provider appropriate for your project. For most users reading this tutorial, that is Supabase Auth.

### 2. Install the Supabase Auth plugin

In the WeWeb editor, click Plugins in the left navbar → Authentication section → Supabase Auth. If you have already added the Supabase backend plugin, the auth plugin auto-detects your Supabase credentials and auto-connects. Click 'Connect' → your Supabase project is linked. In the Supabase Auth plugin settings, configure: Default page for unauthenticated users (the page non-logged-in users are redirected to — typically your login page). This page MUST be public. Set Redirect page after login (the page users land on after successful login — typically your app's dashboard or home page). Click 'Generate' to automatically create the `roles` table and `users_roles` join table in your Supabase database — these are needed for role-based access control later. Review the SMTP configuration notice: for production email delivery (signup confirmation, password reset), configure your own SMTP provider in the Supabase Dashboard → Authentication → Settings → SMTP Settings. Without custom SMTP, Supabase's shared email server has low rate limits and poor deliverability.

**Expected result:** The Supabase Auth plugin is connected to your project. The login page and dashboard page are set as redirect targets. The roles table exists in your Supabase database.

### 3. Build the login page with email and password

Create or navigate to your login page. This page must be set to Public in Page settings → Access control. Add a Form Container → inside it add: an Input element (type: email, name: 'email', required validation), an Input element (type: password, name: 'password', required validation), and a Button ('Sign in'). Add a workflow to the Form Container's On submit event → Action: Supabase Auth → Log in → bind Email to formContainer['formData'].email and Password to formContainer['formData'].password. Add a success branch: if login succeeds, the plugin automatically redirects to the page you configured. For explicit navigation: add Navigate action → your dashboard page. Add an error branch: Change variable value → 'loginError' String → 'Invalid email or password' → bind a Text element below the button to display this error message. The error text element's display should be bound to `loginError.length > 0`.

**Expected result:** The login page accepts email and password. On success, the user is redirected to the dashboard. On failure, an error message appears below the form.

### 4. Build the signup page

Create a signup page (also public). The signup form needs: email input, password input, optional confirm password input. Add a Form Container → On submit workflow → Supabase Auth → Sign up → bind Email and Password fields. If you are requiring password confirmation, add a custom validation formula on the confirm_password input: `formContainer['formData'].password === formContainer['formData'].confirm_password`. In Supabase, email confirmation is enabled by default — users receive an email and must click a confirmation link before they can log in. In this case, after signup, do not auto-redirect to the dashboard. Instead, show a message: 'Please check your email and click the confirmation link to activate your account.' If you want to disable email confirmation for faster onboarding: go to Supabase Dashboard → Authentication → Providers → Email → disable 'Confirm email'. Only do this for internal tools or during development — production apps should keep confirmation enabled to verify email addresses.

**Expected result:** New users can register. If email confirmation is enabled, they receive a confirmation email. If disabled, they are logged in immediately after signup.

### 5. Add social login with Google OAuth

Social login requires two steps: configuring the OAuth provider in Supabase (outside WeWeb), then calling it from WeWeb. OUTSIDE WEWEB — in Supabase Dashboard: go to Authentication → Providers → Google → toggle Enable. Create a Google OAuth app: go to console.cloud.google.com → APIs & Services → Credentials → Create OAuth 2.0 Client ID (Web application type). Authorized redirect URI: paste your Supabase callback URL shown in the Supabase Google provider settings (format: https://[project-ref].supabase.co/auth/v1/callback). Copy the Client ID and Client Secret from Google → paste into Supabase → Save. IN WEWEB: on your login page, add a Button ('Continue with Google'). Add a workflow: On click → Supabase Auth → Login with provider → select 'google' → Redirect to: your post-login page URL. The redirect page after OAuth login MUST be public. When the OAuth flow completes, Supabase redirects back to WeWeb with a token in the URL. WeWeb's Supabase Auth plugin reads this token automatically and logs the user in. For multiple social providers, repeat this process (GitHub, Apple, LinkedIn, etc.) — each requires its own OAuth app setup outside WeWeb.

**Expected result:** Clicking 'Continue with Google' opens a Google consent screen. After approval, the user is logged into your WeWeb app.

### 6. Implement password reset flow

Password reset requires a dedicated reset page and a two-step email flow. Step 1 — Request reset: Add a 'Forgot password?' link on the login page. It navigates to a Reset Password Request page (public). This page has a single email input and a submit button. On submit workflow: Supabase Auth → Reset password → bind Email to the input value. This triggers Supabase to send a password reset email. After the action, show a message: 'Check your email for a password reset link.' OUTSIDE WEWEB — in Supabase Dashboard: Authentication → Email Templates → Reset Password. The default template links to your Supabase auth URL. For WeWeb, change the redirect URL to your WeWeb reset confirmation page: `https://yourdomain.com/reset-confirm?token={{ .Token }}`. Step 2 — Set new password: Create a Reset Confirm page (public, URL: /reset-confirm). This page has a new password input and confirm password input. On page load workflow: extract the token from the URL query variable. On submit: Supabase Auth → Update user → bind new password. After success, navigate to the login page with a success message.

**Expected result:** Users receive a reset email. Clicking the link lands on your reset confirmation page where they enter a new password.

### 7. Access the current user's data in bindings and workflows

After successful login, WeWeb's Supabase Auth plugin stores the user object at `wwContext.user`. Access it in any binding formula throughout your app. Common bindings: Display user's name: `wwContext.user.user_metadata.full_name || wwContext.user.email`. Show/hide content based on login state: bind Conditional Rendering to `wwContext.user !== null`. The user's ID: `wwContext.user.id`. The user's email: `wwContext.user.email`. User roles (after using the Generate button): `wwContext.user.roles` (array of role objects). To use the current user's ID in a Supabase collection filter (e.g., fetch only this user's records): in the collection's Filters section, add: `user_id equals [plug icon] → wwContext.user?.id`. Enable 'Ignore if empty' so the collection doesn't run when the user is not logged in. Logout: add a workflow to any button: Supabase Auth → Log out → then Navigate to the login page. After logout, `wwContext.user` becomes null and any collection with user-based filters automatically refetches empty.

```
// Injection point: binding formula examples for use throughout WeWeb

// Check if user is logged in:
wwContext.user !== null

// Display user's name (with fallback to email):
wwContext.user?.user_metadata?.full_name || wwContext.user?.email || 'Guest'

// Check if user has a specific role:
wwContext.user?.roles?.some(r => r.name === 'admin')

// User's avatar URL (if set in user_metadata):
wwContext.user?.user_metadata?.avatar_url

// Filter a collection to the current user's records:
// Collection filter: user_id equals wwContext.user?.id

// Check if email is confirmed:
wwContext.user?.email_confirmed_at !== null
```

**Expected result:** User data (name, email, roles, ID) is accessible in bindings throughout the app. Collections automatically filter to the current user's data.

## Complete code example

File: `auth-login-workflow.js`

```javascript
// Injection point: Workflow → Custom JavaScript action
// Use this to handle auth state on protected pages
// Run this action in a Project workflow triggered 'On page load'
// to redirect unauthenticated users away from protected pages

// Note: WeWeb's Supabase Auth plugin handles this automatically
// via the 'Default page for unauthenticated users' setting.
// This custom JS is for more granular control (e.g., role-based redirects)

const user = wwContext.user;

if (!user) {
  // User not logged in — will be handled by plugin redirect
  // Return early, no action needed here
  return { authenticated: false };
}

// Check if the user's email is confirmed
if (!user.email_confirmed_at) {
  // Redirect to an 'awaiting confirmation' page
  return { authenticated: false, reason: 'email_not_confirmed' };
}

// Log user info for debugging (remove in production)
console.log('Authenticated user:', user.id, user.email);
console.log('User roles:', user.roles?.map(r => r.name).join(', '));

return {
  authenticated: true,
  userId: user.id,
  email: user.email,
  isAdmin: user.roles?.some(r => r.name === 'admin') || false
};
```

## Common mistakes

- **Setting the OAuth callback redirect page as a protected (non-public) page, causing an infinite redirect loop** — undefined Fix: The page that users land on after social login (Google, GitHub, etc.) MUST be set to Public in Page settings → Access control. This is because the OAuth callback reads the authentication cookie before the user is fully logged in. If the landing page is protected, WeWeb redirects to login, which redirects to Google, creating a loop. After the auth cookie is set on the public redirect page, navigate the user to the protected dashboard.
- **Using WeWeb Auth (the built-in proof-of-concept auth) for a production app** — undefined Fix: WeWeb's own documentation explicitly marks WeWeb Auth as not suitable for production or large user bases. Switch to Supabase Auth, Auth0, or Xano Auth before launch. WeWeb Auth stores data in WeWeb's infrastructure, has limited features, and critically: deleting the plugin permanently deletes all users with no recovery.
- **Not configuring custom SMTP in Supabase, causing confirmation emails to fail or go to spam** — undefined Fix: Supabase's shared email service has strict rate limits (2 emails/hour on free tier) and low deliverability. For production: Supabase Dashboard → Authentication → Settings → SMTP Settings → enable custom SMTP → configure with Resend, SendGrid, or Postmark. Resend has a generous free tier (3,000 emails/month) and is the recommended choice in the WeWeb community.
- **Accessing wwContext.user before the auth plugin has initialized, causing null reference errors on page load** — undefined Fix: Use optional chaining in all user-related bindings: wwContext.user?.email instead of wwContext.user.email. For critical auth checks, add an 'Ignore if empty' condition or check wwContext.user !== null before the binding evaluation. The auth plugin initializes asynchronously — briefly, user may be null even for logged-in users during the initial page render.

## Best practices

- Use Supabase Auth for new projects — it integrates natively with the Supabase data source plugin and auto-forwards tokens to all database operations
- Always configure the post-OAuth redirect page as Public — OAuth callbacks cannot land on protected pages
- Set up custom SMTP in Supabase before going live — the shared email server is rate-limited and unreliable for production
- Use the Generate button in the Supabase Auth plugin settings to auto-create the roles and users_roles tables before building RBAC
- Guard all user-related bindings with optional chaining (user?.email) to prevent errors during the authentication initialization window
- Store additional user profile data in Supabase's profiles table (not just user_metadata) — create a profiles table that references auth.users and populate it via a database trigger on user creation
- Never rely solely on frontend auth state for data security — backend RLS policies are the true security layer

## Frequently asked questions

### Which authentication provider should I choose for my WeWeb project: Supabase Auth or Auth0?

Choose Supabase Auth unless you have specific enterprise requirements. Supabase Auth integrates natively with WeWeb's Supabase plugin, auto-forwards tokens to database operations, and is free for up to 50,000 MAU. Auth0 is the better choice when you need: SAML SSO for enterprise customers (Okta, Azure AD), advanced MFA requirements, compliance certifications beyond what Supabase offers, custom rules/actions in the auth pipeline, or your organization already uses Auth0 for other systems. Auth0 free tier is limited to 7,000 MAU.

### How do I persist the logged-in user's session across page refreshes in WeWeb?

WeWeb's Supabase Auth plugin handles session persistence automatically. The session token is stored in localStorage and the plugin reads it on every page load. As long as the session has not expired (Supabase default: 1 hour access token, 7-day refresh window), the user remains logged in across refreshes and browser reopens. You do not need to implement any custom session persistence code.

### Can WeWeb apps support multi-factor authentication (MFA)?

Supabase Auth added TOTP-based MFA (Google Authenticator, Authy) in 2024. Configure it in Supabase Dashboard → Authentication → Multi-Factor Authentication. WeWeb does not have a built-in MFA UI — you need to build the enrollment and verification pages manually: a 'Set up MFA' page with a QR code generator (Supabase provides the enrollment data), and a 'Verify MFA' step in your login flow that appears after password verification. Auth0 has more mature MFA support with built-in UI if advanced MFA is a core requirement.

### How do I handle users who sign up with Google and later try to sign in with email/password?

By default, Supabase creates separate accounts for email and social login even with the same email address. To link accounts: enable 'Link accounts' in Supabase Dashboard → Authentication → Settings (if available in your Supabase version) or handle this in a Supabase Edge Function using the admin API to merge accounts. The simpler UX solution: on your login page, display only the login method the user originally signed up with. You can detect this by checking the user's app_metadata.provider field in Supabase, and showing/hiding the email form or Google button accordingly.

---

Source: https://www.rapidevelopers.com/weweb-tutorial/weweb-user-authentication
© RapidDev — https://www.rapidevelopers.com/weweb-tutorial/weweb-user-authentication
