docs: update phone auth (#21022)

Co-authored-by: Charis Lam <26616127+charislam@users.noreply.github.com>
This commit is contained in:
Kang MingandCharis Lam authored and GitHub committed 2024-02-06 18:45:08 +00:00
1 parent 6781437dff
commit 30d60342df
7 files changed
+322 -928

No files matched your search

+249 -1
View File
@@ -28,7 +28,7 @@ There are several reasons why you might want to add phone login to your applicat
## Set up a provider with Supabase Auth
Supabase supports Phone Login with several communications platforms. Follow the guides below to set up a provider with Supabase Auth.
To use Phone Login, you first need to set up a Phone provider. Supabase supports Phone Login with several communications platforms. Follow the guides below to set up your provider.
<div className="grid grid-cols-1 md:grid-cols-12 gap-10 not-prose py-8">
{PhoneLoginsItems.map((item) => (
@@ -47,6 +47,254 @@ Supabase supports Phone Login with several communications platforms. Follow the
</div>
## Using Phone Login
You can use Phone Login to:
- [Sign up a user with phone number and password](/docs/guides/auth/phone-login#sign-up-a-user-with-phone-number-and-password)
- [Sign in a user with a One Time Password (OTP)](/docs/guides/auth/phone-login#sign-in-a-user-with-otp)
- [Update a user's phone number](/docs/guides/auth/phone-login#update-a-users-phone-number)
Each of these flows sends the user an SMS containing a six-digit PIN, which you must [verify](/docs/guides/auth/phone-login#verify-a-user) to complete the flow.
### Sign up a user with phone number and password
You can use a user's mobile phone number, instead of an email address, when they sign up with a password.
This practice is usually discouraged because phone networks often recycle mobile phone numbers. Anyone receiving a recycled phone number gets access to the original user's account. To mitigate this risk, [implement MFA](/docs/guides/auth/auth-mfa).
To sign up the user, call [`signUp()`](/docs/reference/javascript/auth-signup) with their phone number and password:
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
```js
const {
data,
error,
} = await supabase.auth.signUp({
phone: '+13334445555',
password: 'some-password',
})
```
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
```kotlin
supabase.auth.signUpWith(Phone) {
phone = "+13334445555"
password = "some-password"
}
```
</TabPanel>
<TabPanel id="http" label="HTTP">
```bash
curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/signup' \
-H "apikey: SUPABASE_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "+13334445555",
"password": "some-password"
}'
```
</TabPanel>
</Tabs>
The user receives an SMS with a 6-digit pin that you must [verify](/docs/guides/auth/phone-login#verify-a-user) within 60 seconds.
After their phone number is verified, the user can use their phone number and password to sign in with needing to reverify each time:
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
```js
const { user, error } = await supabase.auth.signInWithPassword({
phone: '+13334445555',
password: 'some-password',
})
```
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
```kotlin
supabase.auth.signInWith(Phone) {
phone = "+13334445555"
password = "some-password"
}
```
</TabPanel>
<TabPanel id="http" label="HTTP">
```bash
curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/token?grant_type=password' \
-H "apikey: SUPABASE_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "+13334445555",
"password": "some-password"
}'
```
</TabPanel>
</Tabs>
### Sign in a user with OTP
With OTP, a user can sign in without setting a password on their account. They need to verify their phone number each time they sign in.
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
```js
const { data, error } = await supabase.auth.signInWithOtp({
phone: '+13334445555',
})
```
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
```kotlin
supabase.auth.signInWith(OTP) {
phone = "+13334445555"
}
```
</TabPanel>
<TabPanel id="http" label="HTTP">
```bash
curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/otp' \
-H "apikey: SUPABASE_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "+13334445555"
}'
```
</TabPanel>
</Tabs>
The user receives an SMS with a 6-digit pin that you must [verify](/docs/guides/auth/phone-login#verify-a-user) within 60 seconds.
### Update a user's phone number
To update a user's phone number, the user must be logged in. Call [`updateUser()`](/docs/reference/javascript/auth-updateuser) with their phone number:
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
```js
const { data, error } = await supabase.auth.updateUser({
phone: '123456789'
})
```
</TabPanel>
</Tabs>
The user receives an SMS with a 6-digit pin that you must [verify](/docs/guides/auth/phone-login#verify-a-user) within 60 seconds.
### Verify a user
To verify the one-time password (OTP) sent to the user's phone number, call [`verifyOtp()`](/docs/reference/javascript/auth-verifyotp) with the phone number and OTP:
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
You should present a form to the user so they can input the 6 digit pin, then send it along with the phone number to `verifyOtp`:
```js
const {
data: { session },
error,
} = await supabase.auth.verifyOtp({
phone: '+13334445555',
token: '123456',
type: 'sms'
})
```
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
You should present a form to the user so they can input the 6 digit pin, then send it along with the phone number to `verifyPhoneOtp`:
```kotlin
supabase.auth.verifyPhoneOtp(
type = OtpType.Phone.SMS,
phone = "+13334445555",
token = "123456"
)
```
</TabPanel>
<TabPanel id="http" label="HTTP">
```bash
curl -X POST 'https://<PROJECT_REF>.supabase.co/auth/v1/verify' \
-H "apikey: <SUPABASE_KEY>" \
-H "Content-Type: application/json" \
-d '{
"type": "sms",
"phone": "+13334445555",
"token": "123456"
}'
```
</TabPanel>
</Tabs>
If successful the user will now be logged in and you should receive a valid session like:
```json
{
"access_token": "<ACCESS_TOKEN>",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "<REFRESH_TOKEN>"
}
```
The access token can be sent in the Authorization header as a Bearer token for any CRUD operations on supabase-js. See our guide on [Row Level Security](/docs/guides/auth#row-level-security) for more info on restricting access on a user basis.
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page
@@ -12,41 +12,23 @@ Authenticating users via SMS can become expensive. Adjust your project's rate li
</Admonition>
## Overview
## Prerequisites
In this guide we'll show you how to authenticate your users with SMS based OTP (One-Time Password) tokens.
You'll need:
There are two reasons to use Supabase SMS OTP tokens:
- You want users to log in with mobile + password, and the mobile should be verified via SMS
- You want users to log in with mobile ONLY (i.e. passwordless login)
We'll cover:
- [Finding your MessageBird credentials](#finding-your-messagebird-credentials)
- [Using OTP with password based logins](#using-otp-with-password-based-logins)
- [Using OTP as a passwordless sign-in mechanism](#using-otp-as-a-passwordless-sign-in-mechanism)
What you'll need:
- A MessageBird account (sign up here: https://dashboard.messagebird.com/en/sign-up)
- A Supabase project (create one here: https://supabase.com/dashboard)
- A MessageBird account (sign up [here](https://dashboard.messagebird.com/en/sign-up))
- A Supabase project (create one [here](https://supabase.com/dashboard))
- A mobile phone capable of receiving SMS
## Steps
## Set up MessageBird as your SMS provider
### Finding your MessageBird credentials
Start by logging into your MessageBird account and verify the mobile number you'll be using to test with: https://dashboard.messagebird.com/en/getting-started/sms
This is the number that will be receiving the SMS OTPs.
Start by logging into your MessageBird account and verify the mobile number you'll be using to test with [here](https://dashboard.messagebird.com/en/getting-started/sms). This is the number that will be receiving the SMS OTPs.
![Verify your own phone number](/docs/img/guides/auth-messagebird/1.png)
![Get your API Keys](/docs/img/guides/auth-messagebird/2.png)
Navigate to the [dashboard settings](https://dashboard.messagebird.com/en/settings/sms) to set the default originator. The messagebird originator is the name or number from which the message is sent.
For more information, you can refer to the messagebird article on choosing an originator [here](https://support.messagebird.com/hc/en-us/articles/115002628665-Choosing-an-originator)
Navigate to the [dashboard settings](https://dashboard.messagebird.com/en/settings/sms) to set the default originator. The messagebird originator is the name or number from which the message is sent. For more information, you can refer to the messagebird article on choosing an originator [here](https://support.messagebird.com/hc/en-us/articles/115002628665-Choosing-an-originator)
![Set the default originator](/docs/img/guides/auth-messagebird/3.png)
@@ -61,8 +43,11 @@ You should see an option to enable the Phone provider.
Toggle it on, and copy the 2 values over from the Messagebird dashboard. Click save.
Note: If you use the Test API Key, the OTP will not be delivered to the mobile number specified but messagebird will log the response in the dashboard.
If the Live API Key is used instead, the OTP will be delivered and there will be a deduction in your free credits.
<Admonition>
If you use the Test API Key, the OTP will not be delivered to the mobile number specified but messagebird will log the response in the dashboard. If the Live API Key is used instead, the OTP will be delivered and there will be a deduction in your free credits.
</Admonition>
Plugin MessageBird credentials
@@ -76,281 +61,14 @@ Go to [Auth > Templates](https://supabase.com/dashboard/project/_/auth/templates
Use the variable `.Code` in the template to display the code.
### Using OTP with password based logins
## Next steps
In this use scenario we'll be using the user's mobile phone number as an alternative to an email address when signing up along with a password. You may want to think hard about the permanency of this however. It is not uncommon for mobile phone numbers to be recycled by phone networks when users cancel their phone contracts or move countries, therefore granting access to the user's account to whoever takes over the phone number in the future. Soon we'll add multi-factor auth, which will mitigate this risk, but for now you may want to give some thought to allowing your users to recover their account by some other means in an emergency.
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
Using supabase-js on the client you'll want to use the same `signUp` method that you'd use for email based sign ups, but with the `phone` param instead of the `email param`:
```js
const {
data: { user, session },
error,
} = await supabase.auth.signUp({
phone: '+13334445555',
password: 'some-password',
})
```
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
```kotlin
supabase.auth.signUpWith(Phone) {
phone = "+13334445555"
password = "some-password"
}
```
</TabPanel>
<TabPanel id="http" label="HTTP">
```bash
curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/signup' \
-H "apikey: SUPABASE_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "+13334445555",
"password": "some-password"
}'
```
</TabPanel>
</Tabs>
The user will now receive an SMS with a 6-digit pin that you will need to receive from them within 60-seconds before they can login to their account.
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
You should present a form to the user so they can input the 6 digit pin, then send it along with the phone number to `verifyOtp`:
```js
const {
data: { session },
error,
} = await supabase.auth.verifyOtp({
phone: '+13334445555',
token: '123456',
})
```
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
You should present a form to the user so they can input the 6 digit pin, then send it along with the phone number to `verifyPhoneOtp`:
```kotlin
supabase.auth.verifyPhoneOtp(
type = OtpType.Phone.SMS,
phone = "+13334445555",
token = "123456"
)
```
</TabPanel>
<TabPanel id="http" label="HTTP">
```bash
curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/verify' \
-H "apikey: SUPABASE_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "sms",
"phone": "+13334445555",
"token": "123456"
}'
```
</TabPanel>
</Tabs>
If successful the user will now be logged in and you should receive a valid session like:
```json
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNjI3MjkxNTc3LCJzdWIiOiJmYTA2NTQ1Zi1kYmI1LTQxY2EtYjk1NC1kOGUyOTg4YzcxOTEiLCJlbWFpbCI6IiIsInBob25lIjoiNjU4NzUyMjAyOSIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6InBob25lIn0sInVzZXJfbWV0YWRhdGEiOnt9LCJyb2xlIjoiYXV0aGVudGljYXRlZCJ9.1BqRi0NbS_yr1f6hnr4q3s1ylMR3c1vkiJ4e_N55dhM",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "LSp8LglPPvf0DxGMSj-vaQ"
}
```
The access token can be sent in the Authorization header as a Bearer token for any CRUD operations on supabase-js. See our guide on [Row Level Security](/docs/guides/auth#row-level-security) for more info on restricting access on a user basis.
Also now that the mobile has been verified, the user can use the number and password to sign in without needing to verify their number each time:
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
```js
const { user, error } = await supabase.auth.signInWithPassword({
phone: '+13334445555',
password: 'some-password',
})
```
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
```kotlin
supabase.auth.signInWith(Phone) {
phone = "+13334445555"
password = "some-password"
}
```
</TabPanel>
<TabPanel id="http" label="HTTP">
```bash
curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/token?grant_type=password' \
-H "apikey: SUPABASE_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "+13334445555",
"password": "some-password"
}'
```
</TabPanel>
</Tabs>
### Using OTP as a passwordless sign-in mechanism
In this scenario you are granting your user's the ability to login to their account without needing to set a password on their account, all they have to do to log in is verify their mobile each time using the OTP.
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
In JavaScript we can use the `signIn` method with a single parameter: `phone`
```js
const { data, error } = await supabase.auth.signInWithOtp({
phone: '+13334445555',
})
```
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
In Kotlin, we can use the `signInWith(OTP)` method and change the property `phone`
```kotlin
supabase.auth.signInWith(OTP) {
phone = "+13334445555"
}
```
</TabPanel>
<TabPanel id="http" label="HTTP">
```bash
curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/otp' \
-H "apikey: SUPABASE_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "+13334445555"
}'
```
</TabPanel>
</Tabs>
The second step is the same as the previous section, you need to collect the 6-digit pin from the user and pass it along with their phone number to the verify method:
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
```js
const {
data: { session },
error,
} = await supabase.auth.verifyOtp({
phone: '+13334445555',
token: '123456',
})
```
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
```kotlin
supabase.auth.verifyPhoneOtp(
type = OtpType.Phone.SMS,
phone = "+13334445555",
token = "123456"
)
```
</TabPanel>
<TabPanel id="http" label="HTTP">
```bash
curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/verify' \
-H "apikey: SUPABASE_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "sms",
"phone": "+13334445555",
"token": "123456"
}'
```
</TabPanel>
</Tabs>
and the response should also be the same as above:
```json
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNjI3MjkxNTc3LCJzdWIiOiJmYTA2NTQ1Zi1kYmI1LTQxY2EtYjk1NC1kOGUyOTg4YzcxOTEiLCJlbWFpbCI6IiIsInBob25lIjoiNjU4NzUyMjAyOSIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6InBob25lIn0sInVzZXJfbWV0YWRhdGEiOnt9LCJyb2xlIjoiYXV0aGVudGljYXRlZCJ9.1BqRi0NbS_yr1f6hnr4q3s1ylMR3c1vkiJ4e_N55dhM",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "LSp8LglPPvf0DxGMSj-vaQ"
}
```
The user does not have a password therefore will need to sign in via this method each time they want to access your service.
To implement Phone Login, see the docs on [using Phone Login](/docs/guides/auth/phone-login#using-phone-login).
## Resources
- [MessageBird Signup](https://dashboard.messagebird.com/en/sign-up)
- [Supabase Dashboard](https://supabase.com/dashboard)
- [Supabase Row Level Security](/docs/guides/auth#row-level-security)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
@@ -13,14 +13,9 @@ Authenticating users via SMS can become expensive. Adjust your project's rate li
</Admonition>
In this guide we'll show you how to authenticate your users with SMS based One-Time Password (OTP) tokens.
## Preqrequisites
There are two reasons to use Supabase SMS OTP tokens:
- You want users to log in with a phone number and password, and verify the phone number on signup with SMS
- You want users to log in with a phone number ONLY (i.e. passwordless login)
What you'll need:
You'll need:
- Twilio account ([sign up](https://www.twilio.com/try-twilio))
- Supabase project (create one [here](https://supabase.com/dashboard))
@@ -50,11 +45,7 @@ At this time, Twilio Verify is only supported on the `whatsapp` and `sms` channe
## Twilio (Programmable Messaging)
In this section we'll cover:
- [Finding your Twilio credentials](#finding-your-twilio-credentials)
- [Using OTP with password based logins](#using-otp-with-password-based-logins)
- [Using OTP as a passwordless sign-in mechanism](#using-otp-as-a-passwordless-sign-in-mechanism)
In this section, you'll set up Twilio as an SMS provider:
What you'll need:
@@ -62,8 +53,6 @@ What you'll need:
- A Supabase project (create one here: https://supabase.com/dashboard)
- A mobile phone capable of receiving SMS
## Video
<div className="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/akScoPO01bc"
@@ -73,9 +62,7 @@ What you'll need:
></iframe>
</div>
## Steps
### Finding your Twilio credentials
### Setting up your Twilio credentials
Start by logging into your Twilio account and starting a new project: https://www.twilio.com/console/projects/create
@@ -130,278 +117,6 @@ Use the variable `.Code` in the template to display the OTP code. Here's an exam
![example in the SMS template](/docs/img/guides/auth-twilio/9.png)
### Using OTP with password based logins
In this scenario we'll be using the user's mobile phone number and a corresponding password as an alternative to signing up with an email address. Note: please thoroughly consider potential security implications when signing up with a combination of phone number and password. Phone numbers are sometimes recycled by phone networks when users cancel their phone contracts or move countries, thereby granting access to the user's account to the subsequent owner of the phone number. In the near future Supabase will support multifactor authentication, which will mitigate this risk, but for now you may want to consider allowing your users to recover their account by some other means in an emergency.
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
Using supabase-js on the client you'll want to use the same `signUp` method that you'd use for email based sign ups, but with the `phone` param instead of the `email param`:
```js
const {
data: { user, session },
error,
} = await supabase.auth.signUp({
phone: '+13334445555',
password: 'some-password',
})
```
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
```kotlin
supabase.auth.signUpWith(Phone) {
phone = "+13334445555"
password = "some-password"
}
```
</TabPanel>
<TabPanel id="http" label="HTTP">
```bash
curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/signup' \
-H "apikey: SUPABASE_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "+13334445555",
"password": "some-password"
}'
```
</TabPanel>
</Tabs>
The user will now receive an SMS with a 6-digit pin that you will need to receive from them within 60-seconds before they can login to their account.
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
You should present a form to the user so they can input the 6 digit pin, then send it along with the phone number to `verifyOtp`:
```js
const {
data: { session },
error,
} = await supabase.auth.verifyOtp({
phone: '+13334445555',
token: '123456',
type: 'sms',
})
```
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
You should present a form to the user so they can input the 6 digit pin, then send it along with the phone number to `verifyPhoneOtp`:
```kotlin
supabase.auth.verifyPhoneOtp(
type = OtpType.Phone.SMS,
phone = "+13334445555",
token = "123456"
)
```
</TabPanel>
<TabPanel id="http" label="HTTP">
```bash
curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/verify' \
-H "apikey: SUPABASE_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "sms",
"phone": "+13334445555",
"token": "123456"
}'
```
</TabPanel>
</Tabs>
If successful the user will now be logged in and you should receive a valid session like:
```json
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNjI3MjkxNTc3LCJzdWIiOiJmYTA2NTQ1Zi1kYmI1LTQxY2EtYjk1NC1kOGUyOTg4YzcxOTEiLCJlbWFpbCI6IiIsInBob25lIjoiNjU4NzUyMjAyOSIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6InBob25lIn0sInVzZXJfbWV0YWRhdGEiOnt9LCJyb2xlIjoiYXV0aGVudGljYXRlZCJ9.1BqRi0NbS_yr1f6hnr4q3s1ylMR3c1vkiJ4e_N55dhM",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "LSp8LglPPvf0DxGMSj-vaQ"
}
```
The access token can be sent in the Authorization header as a Bearer token for any CRUD operations on supabase-js. See our guide on [Row Level Security](/docs/guides/auth#row-level-security) for more info on restricting access on a user basis.
Also now that the mobile has been verified, the user can use the number and password to sign in without needing to verify their number each time:
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
```js
const { user, error } = await supabase.auth.signInWithPassword({
phone: '+13334445555',
password: 'some-password',
})
```
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
```kotlin
supabase.auth.signInWith(Phone) {
phone = "+13334445555"
password = "some-password"
}
```
</TabPanel>
<TabPanel id="http" label="HTTP">
```bash
curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/token?grant_type=password' \
-H "apikey: SUPABASE_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "+13334445555",
"password": "some-password"
}'
```
</TabPanel>
</Tabs>
### Using OTP as a passwordless sign-in mechanism
In this scenario you are granting your user's the ability to login to their account without needing to set a password on their account, all they have to do to log in is verify their mobile each time using the OTP.
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
In JavaScript we can use the `signIn` method with a single parameter: `phone`
```js
const { data, error } = await supabase.auth.signInWithOtp({
phone: '+13334445555',
})
```
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
In Kotlin, we can use the `signInWith(OTP)` method and change the property `phone`
```kotlin
supabase.auth.signInWith(OTP) {
phone = "+13334445555"
}
```
</TabPanel>
<TabPanel id="http" label="HTTP">
```bash
curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/otp' \
-H "apikey: SUPABASE_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "+13334445555"
}'
```
</TabPanel>
</Tabs>
The second step is the same as the previous section, you need to collect the 6-digit pin from the user and pass it along with their phone number to the verify method:
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
```js
const {
data: { session },
error,
} = await supabase.auth.verifyOtp({
phone: '+13334445555',
token: '123456',
type: 'sms',
})
```
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
```kotlin
supabase.auth.verifyPhoneOtp(
type = OtpType.Phone.SMS,
phone = "+13334445555",
token = "123456"
)
```
</TabPanel>
<TabPanel id="http" label="HTTP">
```bash
curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/verify' \
-H "apikey: SUPABASE_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "sms",
"phone": "+13334445555",
"token": "123456"
}'
```
</TabPanel>
</Tabs>
and the response should also be the same as above:
```json
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNjI3MjkxNTc3LCJzdWIiOiJmYTA2NTQ1Zi1kYmI1LTQxY2EtYjk1NC1kOGUyOTg4YzcxOTEiLCJlbWFpbCI6IiIsInBob25lIjoiNjU4NzUyMjAyOSIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6InBob25lIn0sInVzZXJfbWV0YWRhdGEiOnt9LCJyb2xlIjoiYXV0aGVudGljYXRlZCJ9.1BqRi0NbS_yr1f6hnr4q3s1ylMR3c1vkiJ4e_N55dhM",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "LSp8LglPPvf0DxGMSj-vaQ"
}
```
The user does not have a password therefore will need to sign in via this method each time they want to access your service.
## WhatsApp OTP logins
In some cases, you may wish to use WhatsApp as a delivery channel instead. Here are some examples our users have cited:
@@ -419,44 +134,15 @@ Complete the following steps to use WhatsApp OTP with Twilio Programmable Messag
![Twilio Content SID Image](/docs/img/guides/auth-twilio/twilio_content_sid.png)
3. Register the Twilio Content SID on the Supabase dashboard under Authentication > Providers > Phone > Twilio Content SID. Ensure you have Twilio selected as your phone provider.
Note that you may only use one Twilio Content SID at a time and that Supabase Auth will use the Content Template over the `SMS Message` field when sending WhatsApp messages. Use Twilio Verify if you need to use more than one message template.
<Admonition>
The sign in process with WhatsApp is similar to the sign in process for SMS. Do note the additional `whatsapp` parameter added:
You may only use one Twilio Content SID at a time. Supabase Auth will use the Content Template over the `SMS Message` field when sending WhatsApp messages. Use Twilio Verify if you need to use more than one message template.
```js
const { data, error } = await supabase.auth.signInWithOtp({
phone: '+57336567365',
options: {
channel: 'whatsapp',
},
})
```
</Admonition>
You can also sign up with `whatsapp` as a channel:
## Next steps
```js
const { data, error } = await supabase.auth.signUp({
phone: '+57336567365',
password: 'testsupabasenow',
options: {
channel: 'whatsapp',
},
})
```
There is no change in the verification process, you should continue to use the `sms` type for verification
```js
// After receiving a WhatsApp OTP
const {
data: { session },
error,
} = await supabase.auth.verifyOtp({
phone: '+57336567365',
token: '123456',
type: 'sms',
})
```
To implement Phone Login, see the docs on [using Phone Login](/docs/guides/auth/phone-login#using-phone-login).
## Resources
@@ -12,28 +12,15 @@ Authenticating users via SMS can become expensive. Adjust your project's rate li
</Admonition>
## Overview
## Prerequisites
In this guide we'll show you how to authenticate your users with SMS based OTP (One-Time Password) tokens.
There are two reasons to use Supabase SMS OTP tokens:
- You want users to log in with mobile + password, and the mobile should be verified via SMS
- You want users to log in with mobile ONLY (i.e. passwordless login)
We'll cover:
- [Getting your Vonage API Key](#finding-your-vonage-api-key)
- [Using OTP with password based logins](#using-otp-with-password-based-logins)
- [Using OTP as a passwordless sign-in mechanism](#using-otp-as-a-passwordless-sign-in-mechanism)
What you'll need:
You'll need:
- A Vonage account (sign up here: https://dashboard.nexmo.com/sign-up)
- A Supabase project (create one here: https://supabase.com/dashboard)
- A mobile phone capable of receiving SMS
## Steps
## Set up Vonage as an SMS provider
### Getting your Vonage credentials
@@ -71,281 +58,14 @@ Go to [Auth > Templates](https://supabase.com/dashboard/project/_/auth/templates
Use the variable `.Code` in the template to display the code.
### Using OTP with password based logins
## Next steps
In this use scenario we'll be using the user's mobile phone number as an alternative to an email address when signing up along with a password. You may want to think hard about the permanency of this however. It is not uncommon for mobile phone numbers to be recycled by phone networks when users cancel their phone contracts or move countries, therefore granting access to the user's account to whoever takes over the phone number in the future.
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
Using supabase-js on the client you'll want to use the same `signUp` method that you'd use for email based sign ups, but with the `phone` param instead of the `email param`:
```js
const {
data: { user, session },
error,
} = await supabase.auth.signUp({
phone: '491512223334444',
password: 'some-password',
})
```
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
```kotlin
supabase.auth.signUpWith(Phone) {
phone = "+13334445555"
password = "some-password"
}
```
</TabPanel>
<TabPanel id="http" label="HTTP">
```bash
curl -X POST 'https://xxx.supabase.co/auth/v1/signup' \
-H "apikey: SUPABASE_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "491512223334444",
"password": "some-password"
}'
```
</TabPanel>
</Tabs>
The user will now receive an SMS with a 6-digit pin that you will need to receive from them within 60-seconds before they can login to their account.
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
You should present a form to the user so they can input the 6 digit pin, then send it along with the phone number to `verifyOtp`:
```js
const {
data: { session },
error,
} = await supabase.auth.verifyOtp({
phone: '491512223334444',
token: '123456',
})
```
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
You should present a form to the user so they can input the 6 digit pin, then send it along with the phone number to `verifyPhoneOtp`:
```kotlin
supabase.auth.verifyPhoneOtp(
type = OtpType.Phone.SMS,
phone = "+13334445555",
token = "123456"
)
```
</TabPanel>
<TabPanel id="http" label="HTTP">
```bash
curl -X POST 'https://xxx.supabase.co/auth/v1/verify' \
-H "apikey: SUPABASE_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "sms",
"phone": "491512223334444",
"token": "123456"
}'
```
</TabPanel>
</Tabs>
If successful the user will now be logged in and you should receive a valid session like:
```json
{
"access_token": "eyJxxx...",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "yyy..."
}
```
The access token can be sent in the Authorization header as a Bearer token for any CRUD operations on supabase-js. See our guide on [Row Level Security](/docs/guides/auth#row-level-security) for more info on restricting access on a user basis.
Also now that the mobile has been verified, the user can use the number and password to sign in without needing to verify their number each time:
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
```js
const { user, error } = await supabase.auth.signInWithPassword({
phone: '491512223334444',
password: 'some-password',
})
```
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
```kotlin
supabase.auth.signInWith(Phone) {
phone = "+13334445555"
password = "some-password"
}
```
</TabPanel>
<TabPanel id="http" label="HTTP">
```bash
curl -X POST 'https://xxx.supabase.co/auth/v1/token?grant_type=password' \
-H "apikey: SUPABASE_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "491512223334444",
"password": "some-password"
}'
```
</TabPanel>
</Tabs>
### Using OTP as a passwordless sign-in mechanism
In this scenario you are granting your user's the ability to login to their account without needing to set a password on their account, all they have to do to log in is verify their mobile each time using the OTP.
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
In JavaScript we can use the `signIn` method with a single parameter: `phone`
```js
const { data, error } = await supabase.auth.signInWithOtp({
phone: '491512223334444',
})
```
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
In Kotlin, we can use the `signInWith(OTP)` method and change the property `phone`
```kotlin
supabase.auth.signInWith(OTP) {
phone = "+13334445555"
}
```
</TabPanel>
<TabPanel id="http" label="HTTP">
```bash
curl -X POST 'https://xxx.supabase.co/auth/v1/otp' \
-H "apikey: SUPABASE_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "491512223334444"
}'
```
</TabPanel>
</Tabs>
The second step is the same as the previous section, you need to collect the 6-digit pin from the user and pass it along with their phone number to the verify method:
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
```js
const {
data: { session },
error,
} = await supabase.auth.verifyOtp({
phone: '491512223334444',
token: '123456',
})
```
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
```kotlin
supabase.auth.verifyPhoneOtp(
type = OtpType.Phone.SMS,
phone = "+13334445555",
token = "123456"
)
```
</TabPanel>
<TabPanel id="http" label="HTTP">
```bash
curl -X POST 'https://xxx.supabase.co/auth/v1/verify' \
-H "apikey: SUPABASE_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "sms",
"phone": "491512223334444",
"token": "123456"
}'
```
</TabPanel>
</Tabs>
and the response should also be the same as above:
```json
{
"access_token": "eyJxxx...",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "yyy..."
}
```
The user does not have a password therefore will need to sign in via this method each time they want to access your service.
To implement Phone Login, see the docs on [using Phone Login](/docs/guides/auth/phone-login#using-phone-login).
## Resources
- [Vonage Signup](https://dashboard.nexmo.com/sign-up)
- [Supabase Dashboard](https://supabase.com/dashboard)
- [Supabase Row Level Security](/docs/guides/auth#row-level-security)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
+45 -15
View File
@@ -239,10 +239,8 @@ functions:
- To fetch the currently logged-in user, refer to [`getUser()`](/docs/reference/javascript/auth-getuser).
examples:
- id: sign-up
name: Sign up
name: Sign up with an email and password
isSpotlight: true
description: |
If the password is larger than 72 chars, it will be truncated to the first 72 chars.
code: |
```js
const { data, error } = await supabase.auth.signUp({
@@ -250,6 +248,34 @@ functions:
password: 'example-password',
})
```
- id: sign-up-phone
name: Sign up with a phone number and password (SMS)
isSpotlight: true
code: |
```js
const { data, error } = await supabase.auth.signUp({
phone: '123456789',
password: 'example-password',
options: {
channel: 'sms'
}
})
```
- id: sign-up-phone-whatsapp
name: Sign up with a phone number and password (whatsapp)
isSpotlight: true
description: |
The user will be sent a WhatsApp message which contains a OTP. By default, a given user can only request a OTP once every 60 seconds. Note that a user will need to have a valid WhatsApp account that is linked to Twilio in order to use this feature.
code: |
```js
const { data, error } = await supabase.auth.signUp({
phone: '123456789',
password: 'example-password',
options: {
channel: 'whatsapp'
}
})
```
- id: sign-up-with-additional-user-metadata
name: Sign up with additional user metadata
isSpotlight: false
@@ -505,12 +531,6 @@ functions:
phone: '+13334445555',
password: 'some-password',
})
// After receiving a SMS with a OTP.
const { data, error } = await supabase.auth.verifyOtp({
phone: '+13334445555',
token: '123456',
})
```
- id: sign-in-with-otp
title: 'signInWithOtp()'
@@ -836,16 +856,28 @@ functions:
isSpotlight: false
code: |
```js
const { data, error } = await supabase.auth.updateUser({email: 'new@email.com'})
const { data, error } = await supabase.auth.updateUser({
email: 'new@email.com'
})
```
- id: update-the-phone-for-an-authenticated-user
name: Update the phone number for an authenticated user
description: Sends a one-time password (OTP) to the new phone number.
isSpotlight: false
code: |
```js
const { data, error } = await supabase.auth.updateUser({
phone: '123456789'
})
```
- id: update-the-password-for-an-authenticated-user
name: Update the password for an authenticated user
isSpotlight: false
description: |
If the password is larger than 72 chars, it will be truncated to the first 72 chars.
code: |
```js
const { data, error } = await supabase.auth.updateUser({password: 'new password'})
const { data, error } = await supabase.auth.updateUser({
password: 'new password'
})
```
- id: update-the-users-metadata
name: Update the user's metadata
@@ -1236,8 +1268,6 @@ functions:
- id: create-a-new-user-with-custom-user-metadata
name: With custom user metadata
isSpotlight: true
description: |
If the password is larger than 72 chars, it will be truncated to the first 72 chars.
code: |
```js
const { data, error } = await supabase.auth.admin.createUser({
-4
View File
@@ -94,8 +94,6 @@ functions:
- id: sign-up
name: Sign up
isSpotlight: true
description: |
If the password is larger than 72 chars, it will be truncated to the first 72 chars.
code: |
```swift
try await supabase.auth.signUp(
@@ -360,8 +358,6 @@ functions:
- id: update-the-password-for-an-authenticated-user
name: Update the password for an authenticated user
isSpotlight: false
description: |
If the password is larger than 72 chars, it will be truncated to the first 72 chars.
code: |
```swift
try await supabase.auth.update(user: UserAttributes(password: "newPassw0rd?"))
-4
View File
@@ -94,8 +94,6 @@ functions:
- id: sign-up
name: Sign up
isSpotlight: true
description: |
If the password is larger than 72 chars, it will be truncated to the first 72 chars.
code: |
```swift
try await supabase.auth.signUp(
@@ -360,8 +358,6 @@ functions:
- id: update-the-password-for-an-authenticated-user
name: Update the password for an authenticated user
isSpotlight: false
description: |
If the password is larger than 72 chars, it will be truncated to the first 72 chars.
code: |
```swift
try await supabase.auth.update(user: UserAttributes(password: "newPassw0rd?"))