How to use the sendPasswordResetEmail() function on the server using the firebase-admin SDK?

你说的曾经没有我的故事 提交于 2020-08-05 19:26:31

问题


In the past, I have used firebase.auth in the web client and once a user creates another user, I link certain security logic:

  • Once the user has been created I send an email to verify your email with the function user.sendEmailVerification ().
  • As the user was created by another user, I assign a default password and use the sendPasswordResetEmail () function so that the user registers his new password.

That has worked well for me so far, but now for many reasons I need to move that logic to my server, for that I'm developing a backend with cloud functions and I'm using the Node.js Firebase Admin SDK version 6.4.0, but I can not find a way to use the functions of user.sendEmailVerification() and sendPasswordResetEmail() to implement the same logic on the server, the closest thing I found was:

  • auth.generateEmailVerificationLink (email)
  • auth.generatePasswordResetLink (email)

But it only generates a link for each one, which by the way the only emailVerification() serves me, the one from generatePasswordReset always tells me:

Try resetting your password again

Your request to reset your password has expired or the link has already been used.

Even though be a new link, and it has not been used.

My 3 questions would be:

  1. How can I make the sendEmailVerification () and sendPasswordResetEmail () functions work on the server?
  2. How can I make the link generated with auth.generatePasswordResetLink (email) work correctly on the server?
  3. Is there any way to use templates and emails on the server that are in firebase auth?

Thank you in advance for sharing your experience with me, with all the programmers' community of stack overflow.


回答1:


  1. Those functions are not available in firebase-admin, but you should be able to run the client-side SDK (firebase) on the server as well. Not exactly a best practice, but it will get the job done. There's a long standing open feature request to support this functionality in the Admin SDK. You will find some helpful tips and workarounds there.
  2. Could be a bug. I would consider reporting it along with a complete and minimal repro. The Admin SDK does have an integration test case for this use case, but it works slightly differently.
  3. Not at the moment. Hopefully, this will be covered when the above feature request is eventually fulfilled.



回答2:


The is a workaround provided here https://github.com/firebase/firebase-admin-node/issues/46

I found a work-around that works well enough for my use case, see below. I'm not sure if this is best practice, but I wanted to keep the emails exactly the same between the server and client requests. Would love to hear about any flaws with this implementation 💡



As suggested above, it uses a three step process to do this:

Acquire a custom token via the admin sdk's createCustomToken(uid)
It converts this custom token to an idToken via the API
It invokes the send email verification endpoint on the API
const functions = require('firebase-functions');
const fetch = require('node-fetch');
const admin = require('firebase-admin');

const apikey = functions.config().project.apikey;
const exchangeCustomTokenEndpoint = `https://identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken?key=${apikey}`;
const sendEmailVerificationEndpoint = `https://identitytoolkit.googleapis.com/v1/accounts:sendOobCode?key=${apikey}`;

module.exports = functions.auth.user().onCreate(async (user) => {
  if (!user.emailVerified) {
    try {
      const customToken = await admin.auth().createCustomToken(user.uid);

      const { idToken } = await fetch(exchangeCustomTokenEndpoint, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          token: customToken,
          returnSecureToken: true,
        }),
      }).then((res) => res.json());

      const response = await fetch(sendEmailVerificationEndpoint, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          requestType: 'VERIFY_EMAIL',
          idToken: idToken,
        }),
      }).then((res) => res.json());

      // eslint-disable-next-line no-console
      console.log(`Sent email verification to ${response.email}`);
    } catch (error) {
      // eslint-disable-next-line no-console
      console.log(error);
    }
  }
});


来源:https://stackoverflow.com/questions/53858536/how-to-use-the-sendpasswordresetemail-function-on-the-server-using-the-firebas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!