メインコンテンツまでスキップ

MessageBirdで電話番号による認証

概要

このガイドでは、SMSベースのOTP(ワンタイム・パスワード)トークンでユーザーを認証する方法を紹介します。

SupabaseのSMS OTPトークンを使用する理由は2つあります。

  • 携帯電話 + パスワードでログインし、携帯電話をSMSで認証したい
  • 携帯電話のみでログインさせたい場合(パスワードなしでのログイン)

以下の内容を説明します。

必要なもの次の通りです。

手順

MessageBirdの認証情報を取得

まず、MessageBirdアカウントにログインし、テストに使用する携帯電話番号を確認します。https://dashboard.messagebird.com/en/getting-started/sms

この番号は、SMS OTPを受信する番号です。

Verify your own phone number

Get your API Keys

ダッシュボードの設定に移動して、デフォルトのOriginatorを設定します。MessageBirdのOriginatorとは、メッセージの送信元となる名前または番号のことです。詳しくはこちらでOriginatorの選択に関するMessageBirdの記事をご覧ください。

Set the default originator

はじめるにあたって、以下の値が必要です。

  • 本番用APIキーとテスト用APIキー(Live API Key / Test API Key)
  • MessageBird originator

SupabaseのダッシュボードのAuth → Settingsページに移動します(https://app.supabase.com/project/YOUR-PROJECT-REF/auth/settings)。

Phone Signup(電話による登録)を有効にするオプションがあります。

Enable Phone Sign-Up

これをオンにして、messagebirdのダッシュボードから2つの値をコピーします。「Sava」をクリックします。

注意:テスト用APIキーを使用した場合、OTPは指定された携帯電話番号に配信されませんが、messagebirdは応答をダッシュボードに記録します。代わりに本番用APIキーを使用した場合、OTPは配信されますが、無料クレジットが差し引かれます。

MessageBirdの認証情報がはいります。

これでバックエンドの設定が完了したので、クライアント側のコードを追加していきましょう。

SMSカスタム・テンプレート

OTPコードを含む電話に送信されるSMSメッセージをカスタマイズできます。これは、ブランド名を記載したり、ウェブサイトのアドレスを表示したりする場合に便利です。

SupabaseのダッシュボードのAuth → Templatesページにアクセスします(https://app.supabase.com/project/YOUR-PROJECT-REF/auth/templates)。

コードを表示するには、テンプレートで変数.Codeを使用します。

パスワード・ベースのログインにOTPを使用

この使用例では、ユーザーの携帯電話番号をEメールアドレスの代わりに使用して、パスワードと一緒にサインアップします。しかし、この保持の仕方についてはよく考えた方がよいでしょう。携帯電話番号は、ユーザーが携帯電話の契約を解除したり、国を移動したりする際に、電話会社によって再利用されることがよくあります。近日中に多要素認証を追加し、このリスクを軽減する予定ですが、現時点では、緊急時にユーザーが他の方法でアカウントを回復できるようにすることを検討してみてはいかがでしょうか。

supabase-jsをクライアントで使用する場合、Eメールベースのサインアップに使用するのと同じsignUpメソッドを使用します。その際に、emailの代わりにphoneパラメーターを使用します。

let { user, error } = await supabase.auth.signUp({
phone: '+13334445555',
password: 'some-password',
})

これで、ユーザーはSMSで6桁のピンを受け取ります。このピンは、ユーザーが自分のアカウントへログインする前の、60秒以内にユーザーから受け取る必要があります。

ユーザーが6桁のピンを入力できるようにフォームを表示し、電話番号と一緒に送信してVerifyOTPを行う必要があります。

let { session, error } = await supabase.auth.verifyOTP({
phone: '+13334445555',
token: '123456',
})

成功した場合、ユーザーはログインし、有効な次のようなセッションを受け取ります。

{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNjI3MjkxNTc3LCJzdWIiOiJmYTA2NTQ1Zi1kYmI1LTQxY2EtYjk1NC1kOGUyOTg4YzcxOTEiLCJlbWFpbCI6IiIsInBob25lIjoiNjU4NzUyMjAyOSIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6InBob25lIn0sInVzZXJfbWV0YWRhdGEiOnt9LCJyb2xlIjoiYXV0aGVudGljYXRlZCJ9.1BqRi0NbS_yr1f6hnr4q3s1ylMR3c1vkiJ4e_N55dhM",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "LSp8LglPPvf0DxGMSj-vaQ"
}

supabase-jsでCRUD操作する際、AuthorizationヘッダーのBearerトークンとしてアクセス・トークンを送信できます。ユーザー単位でのアクセス制限については、「行単位セキュリティー」をご参照ください。

また、携帯電話が認証されたことで、ユーザーは毎回番号を認証する必要がなり、携帯番号とパスワードを使ってサインインできるようになります。

let { user, error } = await supabase.auth.signIn({
phone: '+13334445555',
password: 'some-password',
})

パスワード・レスのサインインの仕組みとしてOTPを使用する場合

このシナリオでは、ユーザーにパスワードを設定することなく、自分のアカウントにログインする機能を提供します。ユーザーは、ワンタイムパスワードを使って毎回携帯電話を認証するだけで、ログインできます。

javascriptでは、signInメソッドにphoneという1つのパラメーターを指定して使用します。

let { user, error } = await supabase.auth.signIn({
phone: '+13334445555',
})

2番目の手順は、前のセクションと同じで、ユーザーから6桁のピンを収集し、電話番号と一緒にverifyメソッドへ渡す必要があります。

let { session, error } = await supabase.auth.verifyOTP({
phone: '+13334445555',
token: '123456',
})

と入力すると、上記のようなレスポンスが返ってきます。

{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNjI3MjkxNTc3LCJzdWIiOiJmYTA2NTQ1Zi1kYmI1LTQxY2EtYjk1NC1kOGUyOTg4YzcxOTEiLCJlbWFpbCI6IiIsInBob25lIjoiNjU4NzUyMjAyOSIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6InBob25lIn0sInVzZXJfbWV0YWRhdGEiOnt9LCJyb2xlIjoiYXV0aGVudGljYXRlZCJ9.1BqRi0NbS_yr1f6hnr4q3s1ylMR3c1vkiJ4e_N55dhM",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "LSp8LglPPvf0DxGMSj-vaQ"
}

このユーザーはパスワードを持っていないため、サービスを利用する際には毎回この方法でサインインする必要があります。

リソース