vonageとsupabaseを利用したパスワード+SMS認証が非常にお手軽にできたので、ドキュメントに載っている関数名や返り値が微妙に異なったりなど古く、かつ英語しかないこともあって簡単に紹介したいと思います。
環境
- node: v18.12.1
{
"dependencies": {
"@supabase/auth-helpers-nextjs": "^0.5.2",
"@supabase/auth-helpers-react": "^0.3.1",
"@supabase/auth-ui-react": "^0.2.6",
"@supabase/supabase-js": "^2.2.1",
"next": "13.0.7",
"react": "18.2.0",
"react-dom": "18.2.0"
"react-hook-form": "^7.41.0"
},
"devDependencies": {
"@types/node": "18.11.17",
"@types/react": "18.0.26",
"@types/react-dom": "18.0.9",
"autoprefixer": "^10.4.13",
"eslint": "8.30.0",
"eslint-config-next": "13.0.7",
"postcss": "^8.4.20",
"tailwindcss": "^3.2.4",
"typescript": "4.9.4"
}
}
準備
Vonageのアカウント作成と、supabase側で認証に必要な最低限の準備をします。
- Vonageのアカウントを作成
- アカウント作成時にクレジットが付与されるのでそれを利用
- supabaseアカウント > プロジェクトを作成
- 今回は無料枠内で済ませる
- supabaseの
https://app.supabase.com/project/[Supabase-ID]/sql
にアクセスして、Quick Start
からUser Management Starter
を選択し実行
supabaseダッシュボードから電話番号による認証を有効化する
https://app.supabase.com/project/[Supabase-ID]/auth/providers
からPhone
を選択し、プロバイダーにVonage
を選択。
その後、API Keyとsecretの入力が要求されるので、Vonage API DashboardのAPI Keyとsecretをそれぞれ入力します。
SMS時の表示名も聞かれますが、こちらは日本向けなら適当な文字列でよいです。
例えばAmazonとかでも行けると思います。
認証する
流れとしては、
電話番号 + password > 電話番号 + SMSに来たtoken
の二段階で承認します。
まずは、ユーザー名パスワードの入力画面です。
import { useForm, SubmitHandler } from "react-hook-form";
import { createBrowserSupabaseClient } from "@supabase/auth-helpers-nextjs";
type AuthInputs = {
phone: string;
password: string;
};
const Hoge = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm<AuthInputs>();
const supabaseClient = createBrowserSupabaseClient();
const onSubmit: SubmitHandler<AuthInputs> = async ({ phone, password }) => {
const { error } = await supabaseClient.auth.signUp({ phone, password });
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label htmlFor="phone">phone</label>
<input {...register("phone")} name="phone" />
{errors.password && <p>phone number is required</p>}
</div>
<div>
<label htmlFor="password">password</label>
<input {...register("password")} name="password" type="password" />
{errors.password && <p>password is required</p>}
</div>
<input type="submit" value="ユーザー作成" />
</form>
);
};
ここの処理が正しくいけていれば、SMSが発信されます。
ちなみに、1送信で0.07ユーロかかります。面白半分に連打すると一瞬でクレジットが消し飛ぶ額です。
await supabaseClient.auth.signUp({ phone, password });
日本の電話番号宛ての場合、番号の頭に81を付与する必要がありました。
その後、別ページでも表示の切り替えでも何でもいいですが、SMSに届いたトークンを以下の関数に渡します。
const { error } = await supabaseClient.auth.verifyOtp({
phone,
token,
type: "sms",
});
これで完了です。
はい、これだけで終了です。終わりです。
これでもうログインできています。簡単ですね。
また、以後のログインの場合はSignUpではなくsignInWithPassword
を使用します。