mirror of
https://github.com/supabase/supabase.git
synced 2026-10-15 06:09:08 +03:00
230 lines
6.7 KiB
Plaintext
230 lines
6.7 KiB
Plaintext
---
|
|
title: Passwordless Authentication
|
|
description: Passwordless authentication block for React SPA with Magic Link and OTP support
|
|
---
|
|
|
|
<BlockPreview name="passwordless-auth-demo" />
|
|
|
|
## Installation
|
|
|
|
<BlockItem
|
|
name="passwordless-auth-react"
|
|
description="All needed components for passwordless authentication with Magic Link and OTP"
|
|
/>
|
|
|
|
## Folder structure
|
|
|
|
This block provides reusable components for passwordless authentication. Unlike framework-specific blocks, this doesn't include routing - you'll integrate these components into your own routing solution.
|
|
|
|
<RegistryBlock itemName="passwordless-auth-react" />
|
|
|
|
## Usage
|
|
|
|
Once you install the block in your React project, you'll get all the necessary components to set up passwordless email authentication with both Magic Link and OTP methods. You'll need to handle routing and navigation yourself.
|
|
|
|
### Getting started
|
|
|
|
After installing the block, you'll need to set up your Supabase client. Create a `.env` file with:
|
|
|
|
```env
|
|
VITE_SUPABASE_URL=
|
|
VITE_SUPABASE_PUBLISHABLE_OR_ANON_KEY=
|
|
```
|
|
|
|
- If you're using supabase.com, you can find these values in the [Connect modal](https://supabase.com/dashboard/project/_?showConnect=true&connectTab=frameworks&framework=nextjs) under App Frameworks or in your project's [API settings](https://supabase.com/dashboard/project/_/settings/api).
|
|
|
|
- If you're using a local instance of Supabase, you can find these values by running `supabase start` or `supabase status` (if you already have it running).
|
|
|
|
## Authentication Methods
|
|
|
|
This block supports two passwordless authentication methods:
|
|
|
|
### Magic Link
|
|
|
|
Magic Links are one-time use URLs sent to the user's email. When clicked, they automatically authenticate the user.
|
|
|
|
**When to use**: Simple, one-click authentication with minimal user interaction.
|
|
|
|
### OTP (One-Time Password)
|
|
|
|
OTPs are 6-digit codes sent to the user's email that they manually enter to authenticate.
|
|
|
|
**When to use**: When you need more control over the authentication flow or for mobile apps.
|
|
|
|
## Components
|
|
|
|
### PasswordlessLoginForm (Recommended)
|
|
|
|
A unified passwordless authentication form. Use the `method` prop to choose between Magic Link or OTP authentication.
|
|
|
|
```tsx
|
|
import { PasswordlessLoginForm } from '@/components/auth/passwordless-login-form'
|
|
|
|
export default function LoginPage() {
|
|
// Defaults to 'magic-link' if method prop is not provided
|
|
return <PasswordlessLoginForm method="magic-link" />
|
|
}
|
|
```
|
|
|
|
**Props:**
|
|
|
|
- `method?: 'magic-link' | 'otp'` - Authentication method (default: `'magic-link'`)
|
|
- `className?: string` - Additional CSS classes
|
|
|
|
**Examples:**
|
|
|
|
```tsx
|
|
// Magic Link authentication
|
|
<PasswordlessLoginForm method="magic-link" />
|
|
|
|
// OTP authentication
|
|
<PasswordlessLoginForm method="otp" />
|
|
```
|
|
|
|
### MagicLinkForm
|
|
|
|
Standalone Magic Link authentication form.
|
|
|
|
```tsx
|
|
import { MagicLinkForm } from '@/components/auth/magic-link-form'
|
|
|
|
export default function LoginPage() {
|
|
return <MagicLinkForm />
|
|
}
|
|
```
|
|
|
|
### OTPRequestForm & OTPVerifyForm
|
|
|
|
Two-step OTP authentication flow.
|
|
|
|
```tsx
|
|
// Request OTP
|
|
import { OTPRequestForm } from '@/components/auth/otp-request-form'
|
|
|
|
export default function RequestPage() {
|
|
return <OTPRequestForm />
|
|
}
|
|
|
|
// Verify OTP
|
|
import { OTPVerifyForm } from '@/components/auth/otp-verify-form'
|
|
|
|
export default function VerifyPage() {
|
|
return <OTPVerifyForm />
|
|
}
|
|
```
|
|
|
|
## Configuration
|
|
|
|
### Email Templates
|
|
|
|
You need to configure your email template based on which method you want to use:
|
|
|
|
#### For Magic Link (Default)
|
|
|
|
1. Go to [Email Templates](https://supabase.com/dashboard/project/_/auth/templates) in the Supabase Dashboard
|
|
2. Select "Magic Link" template
|
|
3. Use the following HTML:
|
|
|
|
```html
|
|
<h2>Magic Link</h2>
|
|
|
|
<p>Follow this link to login:</p>
|
|
<p>
|
|
<a href="{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=email"> Log In </a>
|
|
</p>
|
|
```
|
|
|
|
#### For OTP
|
|
|
|
1. Go to [Email Templates](https://supabase.com/dashboard/project/_/auth/templates) in the Supabase Dashboard
|
|
2. Select "Magic Link" template (yes, the same one)
|
|
3. Replace with the following HTML:
|
|
|
|
```html
|
|
<h2>One Time Login Code</h2>
|
|
|
|
<p>Please enter this code to sign in:</p>
|
|
<h1 style="font-size: 32px; letter-spacing: 4px;">{{ .Token }}</h1>
|
|
<p>This code will expire in 1 hour.</p>
|
|
```
|
|
|
|
<Callout type="info">
|
|
|
|
If you want to support both methods, you can include both the link and the token in your email template.
|
|
|
|
</Callout>
|
|
|
|
### Setting up Redirect URLs
|
|
|
|
1. Set the site URL in the [URL Configuration](https://supabase.com/dashboard/project/_/auth/url-configuration) settings in the Supabase Dashboard.
|
|
|
|
2. Add the following redirect URLs to your [URL Configuration](https://supabase.com/dashboard/project/_/auth/url-configuration):
|
|
|
|
- `http://localhost:3000/auth/confirm` (for development)
|
|
- `https://yourdomain.com/auth/confirm` (for production)
|
|
- `http://localhost:3000/protected` (or your authenticated route)
|
|
|
|
3. Update the redirect paths in the components to point to the logged-in routes in your app. Our examples use `/protected`, but you can set this to whatever fits your app.
|
|
|
|
### Configuration Options
|
|
|
|
#### Disable Auto Sign-Up
|
|
|
|
By default, users are automatically created if they don't exist. To prevent this:
|
|
|
|
```tsx
|
|
const { error } = await supabase.auth.signInWithOtp({
|
|
email,
|
|
options: {
|
|
shouldCreateUser: false, // Only allow existing users
|
|
},
|
|
})
|
|
```
|
|
|
|
#### OTP Expiration
|
|
|
|
Configure OTP expiration in the Supabase Dashboard:
|
|
|
|
1. Go to **Authentication** > **Providers** > **Email**
|
|
2. Find **Email OTP Expiration**
|
|
3. Set custom duration (default: 3600 seconds = 1 hour, max: 86400 seconds = 24 hours)
|
|
|
|
## Security
|
|
|
|
### Rate Limiting
|
|
|
|
By default, users can request a magic link or OTP once every 60 seconds to prevent abuse.
|
|
|
|
### Token Expiration
|
|
|
|
- Magic Links expire after 1 hour by default
|
|
- OTPs expire after 1 hour by default
|
|
|
|
## Troubleshooting
|
|
|
|
### Magic Link not working
|
|
|
|
- Verify redirect URLs are configured in Supabase Dashboard
|
|
- Check email template configuration
|
|
- Check browser console for errors, output them yourself if none are present
|
|
|
|
### OTP not received
|
|
|
|
- Verify email template shows `{{ .Token }}`
|
|
- Check spam folder
|
|
- Verify rate limiting hasn't been triggered (wait 60 seconds)
|
|
|
|
### "Invalid token" error
|
|
|
|
- Check if token has expired (default: 1 hour)
|
|
- Ensure user hasn't already used the token
|
|
- Verify system clock is synchronized
|
|
|
|
## Further reading
|
|
|
|
- [Passwordless email logins](https://supabase.com/docs/guides/auth/auth-email-passwordless)
|
|
- [Magic Link authentication](https://supabase.com/docs/guides/auth/auth-email-passwordless#with-magic-link)
|
|
- [OTP authentication](https://supabase.com/docs/guides/auth/auth-email-passwordless#with-otp)
|
|
- [Email templates](https://supabase.com/docs/guides/auth/auth-email-templates)
|
|
- [Authentication error codes](https://supabase.com/docs/guides/auth/debugging/error-codes)
|