🦹

Supabaseでパスワードをリセットする

2024/02/07に公開2

読んでほしい人

  • 🔑FlutterでSupabaseのメールアドレス認証を使用している人
  • 🔑パスワードをリセットする方法を知りたい人

補足情報

もしかしたら、Gmailだと送られてきたリンクをたどるとエラーが出る!
筆者は以前Appleのメールからマジックリンクをたどってログインはできたのですけど、Gmailは不安定なのかも?

記事の内容

今回はこちらのドキュメントを参考に機能を実装しました。そのまま使うだけでいいので、試してみるのが良いかも?
https://supabase.com/docs/reference/dart/auth-resend

Resend an OTP
Resends a signup confirmation, email change, or phone change email to the user.
Passwordless sign-ins can be resent by calling the signInWithOtp() method again.
Password recovery emails can be resent by calling the resetPasswordForEmail() method again.
This method only resend an email or phone OTP to the user if an initial signup, email change, or phone change request was made.

翻訳すると
ワンタイムパスワードの再送
サインアップの確認、電子メールの変更、または電話の変更の電子メールをユーザーに再送信します。
パスワードなしのサインインは、signInWithOtp() メソッドを再度呼び出すことで再送信できます。
パスワード回復メールは、resetPasswordForEmail() メソッドを再度呼び出すことで再送信できます。
このメソッドは、最初のサインアップ、電子メールによる変更、または電話による変更の要求が行われた場合にのみ、電子メールまたは電話による OTP をユーザに再送信します。

final ResendResponse res = await supabase.auth.resend(
  type: OtpType.email,
  email: 'email@example.com',
);

私はこんな感じのコードを使ってますが、みなさんが試すときは、flutter_hookshooks_riverpodを使わない場合は、flutter_riverpodかStatefulWidgetやStatelessWidgetで使ってみてください。

ロジックのコード:

import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

import '../core/supabase/supabase_mixin.dart';

part 'auth_repository.g.dart';

(keepAlive: true)
SupabaseAuthRepository supabaseAuthRepository(
    SupabaseAuthRepositoryRef supabase) {
  return SupabaseAuthRepository();
}

class SupabaseAuthRepository with SupabaseMixin {
  // Supabaseにアカウントを登録する
  Future<AuthResponse> signUp(String email, String password) async {
    try {
      final response =
          await supabase.client.auth.signUp(password: password, email: email);
      return response;
    } on AuthException catch (e) {
      throw Exception('Error: ${e.message}');
    }
  }

  // Supabaseにログインする
  Future<AuthResponse> signIn(String email, String password) async {
    try {
      final response =
          await supabase.client.auth.signInWithPassword(
            email: email,
            password: password,
          );
      return response;
    } on AuthException catch (e) {
      throw Exception('Error: ${e.message}');
    }
  }

  // パスワードをリセットする
  Future<void> resetPassword(String email) async {
    try {
      await supabase.client.auth.resetPasswordForEmail(email);
    } on AuthException catch (e) {
      throw Exception('Error: ${e.message}');
    }
  }

  // ログアウトする
  Future<void> signOut() async {
    await supabase.client.auth.signOut();
  }
}

View側のコード:

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

import '../../core/exteinsion/media_query_extentiosion.dart';
import '../../core/theme/app_color.dart';
import '../../repository/auth_repository.dart';
import '../component/auth_error_msg.dart';
import '../component/round_button.dart';

class ForgotPage extends HookConsumerWidget with SnackBarMixin {
  const ForgotPage({super.key});

  
  Widget build(BuildContext context, WidgetRef ref) {
    final email = useTextEditingController();
    final width = context.screenWidth;

    return Scaffold(
      backgroundColor: AppColor.grey,
      appBar: AppBar(
        title: const Text('パスワードのリセット'),
      ),
      body: SingleChildScrollView(
        child: SizedBox(
          width: width,
          child: Column(
            children: [
              SizedBox(
                height: MediaQuery.of(context).size.height / 3,
              ),
              const Padding(
                padding: EdgeInsets.only(left: 50),
                child: Align(
                  alignment: Alignment.centerLeft,
                  child: Text('メールアドレス'),
                ),
              ),
              SizedBox(
                width: 300,
                height: 50,
                child: TextFormField(
                  decoration: const InputDecoration(
                    fillColor: AppColor.white,
                    filled: true,
                    hintText: 'メールアドレスを入力',
                    border: OutlineInputBorder(),
                  ),
                  controller: email,
                ),
              ),
              const SizedBox(height: 50),
              AppButton(
                'パスワードをリセットする',
                AppColor.white,
                () async {
                  try {
                    await ref
                        .read(supabaseAuthRepositoryProvider)
                        .resetPassword(email.text);
                  } on Exception catch (e) {
                    if (context.mounted) {
                      showErrorSnackBar(context, e.toString());
                    }
                  }
                },
                AppColor.navy,
                300,
                50,
              ),
            ],
          ),
        ),
      ),
    );
  }
}



最後に

今回はSupabaseのメールアドレスとパスワードの認証機能で、パスワードをリセットする機能をご紹介しました。実際のところGmailではうまくいってないので、何か設定が足りないのかも???
マジックリンクのログインも上手くいかないので、何が原因なのかは不明です🙃

Discussion

134134

想定はパスワードを忘れた場合ですよね
パスワードの再設定の際は、メールのリンクをアプリで受けて、
アプリで再設定する流れですよね?
モバイル端末の場合はディープリンクの設定がいる感じですかね?

JboyHashimotoJboyHashimoto

Chromeのブラウザだと問題があるのかもしれないです。なんか知らないけどうまくいかないんですよね。