Firebase:在 Cloud Functions 中重新验证当前用户

Firebase: Re-authenticate the current user inside a Cloud Function

我正在实现更新当前用户密码的云功能。

基本上,我要遵循的逻辑是:

(Client side)
 0. Complete form and submit the data (current password and new password).

(Backend) 
 1. Get the current user email from the callable function context.
 2. Re-authenticate the current user using the provided current password.
   2.1. If success, change the password and send a notification email.
   2.2. Else, throw an error.

这是我当前的代码:

const { auth, functions } = require("../../services/firebase");
...

exports.updatePassword = functions
  .region("us-central1")
  .runWith({ memory: "1GB", timeoutSeconds: 120 })
  .https.onCall(async (data, context) => {
    const { currentPassowrd, newPassword } = data;

    const { email, uid: userId } = context.auth.token;

    if (!userId) {
      // throw ...
    }

    try {
      // 
      // Problem: `firebase-admin` authentication doesn't include
      // the `signInWithEmailAndPassword()` method...
      //
      await auth.signInWithEmailAndPassword(email, currentPassowrd);

      await auth.updateUser(userId, {
        password: newPassword,
      });

      sendPasswordUpdateEmail(email);
    } catch (err) {
      // ...
      throw AuthErrors.cannotUpdatePassword();
    }
  });

我的问题是 firebase-admin 包不包含 signInWithEmailAndPassword,我需要一种方法来处理这个问题,以在我的函数中检查“currentPassword”是否正确。

我的另一种选择,如果我所描述的方法不可行,是在客户端使用 firebase sdk 更新密码,然后调用 firebase 函数发送通知电子邮件。

严格来说,您不需要 re-authenticate Cloud Function 中的用户:如果您在 Callable Cloud Function 中获得 context.auth.uid 的值,则意味着用户已通过身份验证front-end,因此您可以安全地调用 updateUser() 方法。

如果你想处理当用户让他的设备打开时有人更新他的密码的情况,正如你问题下的评论中所解释的,我建议你使用 reauthenticateWithCredential() 中的方法front-end,其中 re-authenticate 是使用新凭据的用户。

进行如下操作:

import {
    EmailAuthProvider,
    getAuth,
    reauthenticateWithCredential,
} from 'firebase/auth'

const email = auth.currentUser.email;
// Capture the password value
// e.g. via a pop-up window
const password = ...;

const auth = getAuth();
const credential = EmailAuthProvider.credential(
    email,
    password
);
await reauthenticateWithCredential(
    auth.currentUser, 
    credential
);

// If no error is thrown, you can call the Callable Cloud Function, knowing the user has just re-signed-in.