会員管理・認証機能を活用してアプリ開発を行ってみたところ、タイトルに記載したような疑問に直面する機会がありましたので、その実現方法についてこのブログで解説しておきます。
はじめに
mobile backend の会員管理・認証機能を活用して何かアプリを作ってみよう!ということでデモアプリではなくリリースして運用することまで考えアプリを制作をしてみました。その中で「退会」機能の実装のため、「アカウントの削除」機能を実装してみたのですが、以下のエラーが発生してしまいました。
E401001: Authentication error by header incorrect.
日本語にすると「Header不正による認証エラー」です。mobile backend のAPIリクエストはヘッダーにセッショントークン付きでリクエストをする仕様となっているのですが、そのセッショントークンが不正な場合に返却される認証エラーです。例えば、セッショントークンの有効期限が切れている状態で mobile backend にリクエストをすることで発生します。
「アカウント削除機能」実装時の注意点
アプリ内でユーザーがボタンを押すことで、アカウントの削除(ユーザー自身をdelete)が実行されるように実装した場合、ユーザーの行動は以下のようになると思います。
- アプリにログインまたは新規登録とログインをする
- アカウントを削除(ユーザー自身をdelete)する
- アプリの利用をやめるかまたは再び新規登録をする
アプリの利用を辞めるためアカウントを削除する場合、アプリも削除してしまうので特に問題ないのですが、現在のアカウントを捨てて新しいアカウントを作り直すことが目的である場合、アカウント削除のあと再度新規登録をすることが予想されます。
「401001」エラーが発生する状況と原因
上記の行動パターンで、ユーザーがログインまたは新規登録とログインを行ったあとアカウントを削除(ユーザー自身をdelete)を実行し、新規登録を行おうとした場合に、新規登録のリクエストの際「401001」エラーが発生することがわかりました。
このエラー発生の原因は、ログイン中のユーザーが、ユーザー自身をdeleteしたことによりカレントユーザー(現在ログイン中のユーザー)はnullとなりますが、deleteする前にログアウト処理をしていないため、保持中のセッショントークンを無効化できていないことにありました。そのため、再度新規登録のリクエストを行った際にヘッダー不正のエラーとなってしまったようです。
「アカウント削除機能」の正しい実装方法
mobile backend に作成されるアカウント(ユーザー)は、作成時に変更をしていない限り、そのユーザー自身にのみ書き込み権限が付与されている状態です。したがって、ユーザーを削除(delete)するには、必ずそのユーザーでログインをし、そのユーザーがログイン中の状態で削除(delete)を実行する必要があります。しかし、そうなると困りますね。削除(delete)の前にログアウト(セッショントークン無効化)を行うことができません。。
そこで、mobile backend のスクリプト機能を組み合わせ、アカウントを削除(ユーザー自身をdelete)部分の処理を次のような方法で実装してみました。
先にログアウトを実行しセッショントークンをnullとした状態でスクリプトを呼び出し、スクリプト上で別ユーザーを使ってアカウントの削除を実行するという方法です。少し面倒ですが、この方法にすることで、401001エラーは解消することができます。
ただし、すでに気付いた方もいるかもしれませんが、実はもう1つだけ処理を追加で実装しなければこの方法は実現できません。先程述べた以下が影響しているからです。
mobile backend に作成されるアカウント(ユーザー)は、作成時に変更をしていない限り、そのユーザー自身にのみ書き込み権限が付与されている状態です。
したがって、スクリプトからマスターユーザーを使ってユーザーの削除を実行するには、あらかじめ削除対象のユーザーに対し、マスターユーザーの書き込み権限を持たせることが必要となります。
「アカウント作成」時、同時に参照権限の設定はできるか?
マスターユーザーの書き込み権限のタイミングですが、アカウント作成時に付与しておくことをまず考えるかと思います。しかし、mobile backend の仕様上、アカウント作成時に参照権限を設定しようとすると、そのアカウント自身に権限を持たせることができません。
これは、参照権限の設定はユーザーのobjectId(ロールの場合はロール名)を設定する仕様ですが、アカウント作成のタイミングではまだobjectIdが払い出されていない状態ですので、権限ユーザーとして設定することができないためです。
ユーザーに対して他のユーザーやロールの権限を付ける適切なタイミング
これは状況により異なります。今回の場合はアカウントの削除をスクリプト上でマスターユーザーにて行うために参照権限の更新が必要です。逆に、削除しない限りは参照権限の更新は不要です。そこで、アカウント削除の場合は、その処理の直前に権限設定の変更を実施するとよいと思います。
これで「アカウント削除」の実行は無事完了です!
おわりに
いかがでしたでしょうか。直観的に考えると今回のように上手くいかない部分も出てくるかと思いますが、仕組みを考えて実装することでクリアできるかともいます。今回の場合も、「自分自身を削除する」というのはセキュリティ上微妙だったかも?と思えていたら躓かずに最初から管理ユーザーでの処理が思いついたのかも??なんて思いつつ、躓きながら改善しながら開発を進めて技術力を付けていくのも大事ですので、あまり難しく考えずに mobile backend を活用してもらえたら嬉しいです!