SupabaseのAuthでパスワードリセット機能を作る

22078 ワード

初めに

Supabaseのパスワードリセット機能の実装をまとめた記事があまりないなと思ったのでやり方について紹介します。
NextJsを使っています。

使用技術 ・ バージョン

・ "supabase/supabase-js": "1.33.3"
・ "react": "17.0.2"
・ "next": "12.0.9"
・ "typescript": "4.5.5"

ページの作成

まずはsend-emailreset-passwordページを作ります。スタイルのないかなりシンプルなコードですがご容赦ください。
まだリセット処理は記述していません。

send-email.tsx
const SendEmailToResetPassword: NextPage = () => {
  const [email, setEmail] = useState<string>('');
  const [isSend, setIsSend] = useState<boolean>(false);
  const [error, setError] = useState<ApiError | null>(null);
	 
  const handleSubmitEmail = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    // ここでメール送信
  };
  
  const handleSetEmail = (event: React.ChangeEvent<HTMLInputElement>) => {
    setEmail(event.target.value);
  };
  
  if (error) {
    return <p>エラー</p>;
  }
  
  if (isSend) {
    return <p>送信しました</p>;
  }
  
  return (
    <div>
     <p>登録されているメールアドレスを入力してください</p>
     <form onSubmit={handleSubmitEmail}>
        <input value={email} type="email" onChange={handleSetEmail} placeholder="メールアドレス" />
        <button type="submit">送信</button>
      </form>
    </div>
  );
}
reset-password.tsx
const ResetPassword: NextPage = () => {
  const [passwoed, setPassword] = useState<string>('');
  const [isSend, setIsSend] = useState<boolean>(false);
  const [error, setError] = useState<ApiError | null>(null);
	 
  const handleSubmitPassword = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    // ここでパスワードリセット
  };
  
  const handleSetPassword = (event: React.ChangeEvent<HTMLInputElement>) => {
    setPassword(event.target.value);
  };
  
  if (error) {
    return <p>エラー</p>;
  }
  
  if (isSend) {
    return <p>送信しました</p>;
  }
  
  return (
    <div>
     <p>新しいパスワードを入力してください</p>
     <form onSubmit={handleSubmitPassword}>
        <input value={password} type="password" onChange={handleSetPassword} placeholder="パスワード" />
        <button type="submit">送信</button>
      </form>
    </div>
  );
}

リセット処理の記述

それではリセット処理を記述していきましょう。
先ほど作成した二つのページのコード内のSubmit関数
(それぞれhandleSubmitEmailhandleSubmitPassword)に処理を記述していきます。

send-email.tsx
const handleSubmitEmail = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    try {
      const { error } = await supabase.auth.api.resetPasswordForEmail(email, {
        // 送信メールに埋め込まれるリンクのリダイレクト先のURL
	// reset-passwordへ遷移する
        redirectTo: 'http://localhost:3000/reset-password',
      });
      if (error) {
        setError(error);
	throw error;
      }
      setIsSend(true);
    } catch (error) {
      console.log(error);
    }
  };
reset-password.tsx
const handleSubmitPassword = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    try {
      // 新パスワードを引数に入力
      const { error } = await supabase.auth.update({ password: password });
      if (error) {
        setError(error);
	throw error;
      } 
      setIsSend(true);
    } catch (error) {
      console.log(error);
    }
  };

これでsend-emailページ内で登録されているアカウントのメールアドレスを送信すると, そのメールアドレス宛にメールが届きそのメール内のリンクにアクセスすると関数内で指定したリダイレクト先のURLに遷移します。(http://localhost:3000/reset-password)
その中でパスワードを入力して送信することでパスワードのリセットが完了します。

終わりに

困っている方などの参考になれば幸いです。

参考