Login With Email OTP
Email one-time passwords (OTP) are a form of passwordless login where users key in a six digit code sent to their email address to log in to their accounts. By default, a user can only request an OTP once every 60 seconds and they expire after 24 hours.
Setting up email OTP#
To set up email OTP for your Supabase app:
- Enable the email provider in your Supabase Project
- The Site URL represents the default URL that the user will be redirected to after clicking on the email signup confirmation link.
- If a user has not signed up yet, signing in with an OTP will automatically sign up the user. To prevent users from signing up this way, you can set the
shouldCreateUser
option tofalse
. - Navigate to the email template settings and modify the template to include the
{{ .Token }}
variable, for example:
_10<h2>One time login code</h2>_10_10<p>Please enter this code: {{ .Token }}</p>
Signing in a user with email OTP#
When your user signs in, call signInWithOtp() with their email address:
_10const { data, error } = await supabase.auth.signInWithOtp({_10 email: 'example@email.com',_10 options: {_10 // set this to false if you do not want the user to be automatically signed up_10 shouldCreateUser: false,_10 },_10})
If the request was successful, you receive a response with error: null
and a data
object where both user
and session
are null. In this case you can let the user know to check their email inbox.
_10{_10 "data": {_10 "user": null,_10 "session": null_10 },_10 "error": null_10}
Verify OTP to create session#
Provide an input field for the user to key in the one-time code. To verify the code and complete the user's sign in, call verifyOtp() with their email address, the code, and type: "email"
:
_10const {_10 data: { session },_10 error,_10} = await supabase.auth.verifyOtp({_10 email,_10 token: '123456',_10 type: 'email',_10})
If successful the user will now be logged in and you should receive a valid session like:
_10{_10 "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNjI3MjkxNTc3LCJzdWIiOiJmYTA2NTQ1Zi1kYmI1LTQxY2EtYjk1NC1kOGUyOTg4YzcxOTEiLCJlbWFpbCI6IiIsInBob25lIjoiNjU4NzUyMjAyOSIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6InBob25lIn0sInVzZXJfbWV0YWRhdGEiOnt9LCJyb2xlIjoiYXV0aGVudGljYXRlZCJ9.1BqRi0NbS_yr1f6hnr4q3s1ylMR3c1vkiJ4e_N55dhM",_10 "token_type": "bearer",_10 "expires_in": 3600,_10 "refresh_token": "LSp8LglPPvf0DxGMSj-vaQ",_10 "user": {...}_10}