[Firebase Authentication]バックエンドでpasswordユーザーにプロバイダをリンクする方法
はじめに
通常はFirebaseで業務をしています。そのときに、実装した内容を今回は記載していきます。
背景
Firebase Authenticationでpasswordプロバイダのユーザーを管理している。
このときに、他のプロバイダ(googleやmicrosoft.comなど)をバックエンドで行いたい。
公式は、クライアント側で実装する内容をサンプルとしてあげているが、バックエンドのサンプルは存在していない。
今回はなぜ、クライアント側で実装しなかったのか、バックエンドの実装方法を残しておく。
※細かい設定は省いていますが、設定で「同じメールを使用するアカウントをリンクする」が必要なので、事前に設定をしておいてください。
クライアントの実装方法
以下は公式のサンプルです
auth.signInWithPopup(new firebase.auth.OAuthProvider('microsoft.com')).catch(function(error) {
if (error.code === 'auth/account-exists-with-different-credential') {
var pendingCred = error.credential;
var email = error.email;
if (methods[0] === 'password') {
var password = promptUserForPassword();
auth.signInWithEmailAndPassword(email, password).then(function(result) {
return result.user.linkWithCredential(pendingCred);
}).then(function() {
goToApp();
});
return;
}
result.user.linkAndRetrieveDataWithCredential(pendingCred).then(function(usercred) {
goToApp();
});
});
});
}
});
データの流れは以下です。
- プロバイダ認証のポップアップ画面 or リダイレクト画面を表示させる
- ログイン実施
- 「account-exists-with-different-credential」エラー発生する
- エラー発生ときに含まれる返り値のemailとクレデンシャル情報を定数に入れておく
-
fetchSignInMethodsForEmail()
でemailプロバイダ情報を取得 - 非同期でパスワード取得
- 5と6で取得して情報を元に、emailとpassword認証を行う
- 7の返り値の
result.user.linkWithCredential()
に4で取得したクレデンシャル情報を引数を用いて、プロバイダにリンクを行う - プロバイダリンク完了
ここで問題だったのは、6. 非同期でパスワード取得です。仕様上パスワードをFirebase Authenticationのパスワードで管理を行なっていたので、パスワードを取得することができませんでした。
画面を遷移して、パスワードを入力させる画面を出す方法も考えたのですが、UXを考慮してやめました。
なので、バックエンド側で簡潔する方法を考えました。
実装方法(バックエンド)
業務ではmicrosoftプロバイダをリンクさせる必要があったので、サンプルはmicrosoftで記載していきます。
※一部GraphAPIの情報が必要なってきます。
ざっくりな流れは以下です。
- Firebase Authenticationで管理しているUIDを取得する
- 事前にGraphAPIでオブジェクトIDを取得する
-
updateUser()
でプロバイダのリンクを行う
return new Promise(async (resolve, reject) => {
try {
await admin.auth().updateUser(uid, {
providerToLink: {
uid: //microsoftのオブジェクトID,
displayName: //任意の名前,
email: //任意のemail,
phoneNumber: null,
photoURL: null,
providerId: "microsoft.com", // 紐づけたいプロバイダ
},
});
resolve({ code: 200 });
} catch (e) {
reject({ code: 500 });
}
});
ポイントはpriderToLink
です。ここで、uidをきちんとmicrosoftオブジェクトIDを紐づける必要があります。もし、別のidを紐づけてしまうと、正常にプロバイダログインができなくなくなります。
uidに紐づける値は、プロバイダで変わってくると思われます。事前にどんな値が入るのか、調査は必要になってきます。
この後はクライアント側で通常どおり、プロバイダ認証をすれば正常にログインができるかと思います。
さいごに
今回はバックエンドでFirebase Authenticationを実装してみました。みにくいですが、公式のドキュメントはかなり参考になりました。公式のドキュメントを参考にすることで、バックエンドの実装もかなり幅広くなるので、公式のサンプルで解決できない時は、参考にしていこうと思っています。
参考記事
Discussion
test