🙃
SupabaseのEdge FunctionsとFlutterを使用してAuth userの削除機能を実装してみる
背景
FlutterとSupabaseを使用したアプリを開発している時、ユーザーの退会機能を実装が必要になりました。(よくあるケース)
事前準備
- supabaseのプロジェクトが作成されていること
- flutterのアプリとsupabseの繋ぎ込みができていること
- https://supabase.com/docs/guides/functions/quickstart#prerequisites が終えていること
Edge Functions側の実装
SupabseにあるFlutterのドキュメントなどを確認していましたが、Auth userの削除処理について明記されていませんでした。(自分の確認不足でしたらすみません)
そこでEdge Functionsを利用します。
ここではさまざまなユースケースがあり、コードも公開されています。
またTypeScriptのサポートされ、Denoが使用されています。
Edge Functionsの作成
supabase functions new delete-user
./functions/delete-user/index.ts
が生成されます。
生成されたコードを変更します。(エラー処理の部分はきちんと書いていません)
import { serve } from 'https://deno.land/std@0.177.0/http/server.ts';
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2.25.0';
serve(async (req: Request) => {
const reqJson = await req.json();
try {
const supabaseClient = createClient(
Deno.env.get('SUPABASE_URL') ?? '',
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? '',
auth: {
autoRefreshToken: false,
persistSession: false,
},
}
);
const jwt = req.headers.get('Authorization')!.split(' ')[1]
const { data } = await supabaseClient.auth.getUser(jwt);
await supabaseClient.auth.admin.deleteUser(
data.user.id
);
return new Response(JSON.stringify({ success: true }), {
headers: { 'Content-Type': 'application/json' },
status: 200,
});
} catch (error) {
return new Response(JSON.stringify({ error: error.message }), {
headers: { 'Content-Type': 'application/json' },
status: 400,
});
}
});
deleteUserの第二引数でtrue
を設定すると、論理削除がされます。デフォルトはfalse
です。
デプロイ
以下をSupabseプロジェクトのルートで実行するとSupabseにデプロイがされます。
supabase functions deploy delete-user
管理画面を確認するとデプロイされていることを確認できます。
Flutter側の実装
Flutter側の実装としては、基本的に上記で作成したEdge Functionsを呼び出すだけで終わります。
void _deleteAccount(BuildContext context) async {
try {
await supabase.functions.invoke("delete-user");
// 削除後の処理など
} on AuthException catch (error, stackTrace) {
context.showErrorSnackBar(message: error.message);
}
}
まとめ
以上でSupabase のEdge FunctionsとFlutterを使用したユーザーの削除処理ができました。デプロイなども簡単ですしサクッと実装することができました。
ローカル環境での開発もとても簡単にできます。
Discussion
素敵な記事ありがとうございます!Supabaseコミュニティ内でもこちらの記事に助けていただいている話をよく聞きます!
一点ユーザーさんが気づいてくれた点があるのですが、上記のDeno functionだと誰でも好きなユーザーIDを引数として投げることができて、好きなユーザーを削除することができることになってしまいます。もしよろしければこちらのガイドにあるようにAuth headerからfunctionsをコールしているユーザーを特定してそのユーザーを削除する形に編集していただくことって可能でしょうか?
コメントありがとうございます!
こちら修正します🙏
遅くなってしまいました🙏
こちら修正しました!
こちら修正ありがとうございます!ただ、createClientにauth headerを渡してしまうとservice role keyが上書きされユーザーが削除できない気がします。なのでcreateClientではheaderを渡さずに、
getUserにこのようにJWTを渡すことで service role keyの権限を失うことなくユーザー情報を引っ張ってくることができます!
確かにservice role keyが上書きされユーザーが削除できないですね!
こちら反映してあります!
度々有難うございます!