如何在使用Firebase Cloud功能创建用户后发送电子邮件验证?

时间:2017-03-18 09:25:20

标签: firebase firebase-authentication email-verification

我尝试在创建用户后发送验证邮件。由于Firebase本身没办法,我会尝试使用云功能。

我真的找不到很多关于它的文档。到目前为止,我试图做的是:

exports.sendEmailVerification = functions.auth.user().onCreate(event => {
    return user.sendEmailVerification()
});

但我收到用户未定义的错误。

如何创建此功能?

谢谢!

5 个答案:

答案 0 :(得分:6)

@Alexander回答并评论说,只有已登录的用户才能请求发送验证邮件。目前无法通过Cloud Functions中使用的Admin SDK执行此操作,因为这很容易被滥用。

如果您希望将此功能添加到Admin SDK,我建议您file a feature request

与此同时,您可以使用云功能实施自己的电子邮件验证流程。从用户处获得验证码后,您可以使用Admin SDK将其emailVerified属性设置为true。请参阅this section of the Firebase documentation for an example

或者,您也可以通过自己的机制发送电子邮件,但请使用generating the correct email verification link

之前的现有验证流程

答案 1 :(得分:2)

这就是我如何使用Firebase云功能以及小型快速后端服务器成功实现它的方法

每创建一个新用户都会触发Firebase Cloud功能(后台)

  • 此函数将“用户”对象发送到您的api端点

const functions = require('firebase-functions');
const fetch = require('node-fetch');

// Send email verification through express server
exports.sendVerificationEmail = functions.auth.user().onCreate((user) => {
  // Example of API ENPOINT URL 'https://mybackendapi.com/api/verifyemail/'
  return fetch( < API ENDPOINT URL > , {
      method: 'POST',
      body: JSON.stringify({
        user: user
      }),
      headers: {
        "Content-Type": "application/json"
      }
    }).then(res => console.log(res))
    .catch(err => console.log(err));
});

服务器中间件代码

  • verifyEmail用作中间件

// File name 'middleware.js'
import firebase from 'firebase';
import admin from 'firebase-admin';

// Get Service account file from firebase console
// Store it locally - make sure not to commit it to GIT
const serviceAccount = require('<PATH TO serviceAccount.json FILE>');
// Get if from Firebase console and either use environment variables or copy and paste them directly
// review security issues for the second approach
const config = {
  apiKey: process.env.APIKEY,
  authDomain: process.env.AUTHDOMAIN,
  projectId: process.env.PROJECT_ID,
};
// Initialize Firebase Admin
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
});

// Initialize firebase Client
firebase.initializeApp(config);

export const verifyEmail = async(req, res, next) => {
  const sentUser = req.body.user;
  try {
    const customToken = await admin.auth().createCustomToken(sentUser.uid);
    await firebase.auth().signInWithCustomToken(customToken);
    const mycurrentUser = firebase.auth().currentUser;
    await mycurrentUser.sendEmailVerification();
    res.locals.data = mycurrentUser;
    next();
  } catch (err) {
    next(err);
  }
};

服务器代码

// Filename 'app.js'
import express from 'express';
import bodyParser from 'body-parser';
// If you don't use cors, the api will reject request if u call it from Cloud functions
import cors from 'cors';
import {
  verifyEmail
} from './middleware'

app.use(cors());
app.use(bodyParser.urlencoded({
  extended: true,
}));
app.use(bodyParser.json());

const app = express();
// If you use the above example for endpoint then here will be
// '/api/verifyemail/'
app.post('<PATH TO ENDPOINT>', verifyEmail, (req, res, next) => {
  res.json({
    status: 'success',
    data: res.locals.data
  });
  next()
})

此端点将返回完整的用户对象,并将验证电子邮件发送给用户。

我希望这会有所帮助。

答案 2 :(得分:1)

首先查看Firebase here的文档。

当注册阶段完成并导致成功时,异步触发以下函数:

 private void sendVerification() {
             FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
             user.sendEmailVerification().addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if (task.isSuccessful()) {
                         system.print.out("Verification Email sent Champion")
                          }
                         }
                });
}

现在将向用户提供验证电子邮件。单击超链接后,项目服务器将使用Firebase验证用户。

enter image description here

您如何确定用户是否确认了他们的电子邮件?

 private void checkEmail() {

    FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();

    if (user.isEmailVerified()) {
           // email verified ...
    } else {
       // error : email not verified ...
    }
}

可悲的是,您可能无法自定义验证电子邮件的内容/正文(我已经与Firebase大量对应,以提供其他不那么可怕的模板)。您可以更改标题或邮件发件人ID,但这就是它的全部内容。

除非您使用自己支持的Web重新链接应用程序。 Here

答案 3 :(得分:1)

Version 6.2.0 of the Node.js Admin SDK于2018年11月19日发布以来,就可以在Cloud Function中通过auth.generateEmailVerificationLink()方法生成用于电子邮件验证的链接。

您将在documentation中找到更多详细信息和一些代码示例。

然后,您可以通过Mailgun,Sendgrid或任何其他电子邮件微服务发送包含此链接的电子邮件。您会在这里找到Cloud Function sample,其中显示了如何从Cloud Function发送电子邮件。

答案 4 :(得分:0)

如果您想让Admin SDK这样做,那么到目前为止,除了生成电子邮件验证链接并使用您自己的电子邮件传递系统进行发送外,别无选择。

但是

您可以在云功能上编写REST请求,并以此方式启动电子邮件验证邮件。

export async function verifyEmail(apiKey : string, accessToken : string) {
    // Create date for POST request
    const options = {
        method: 'POST',
        url: 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/getOobConfirmationCode',
        params: {
            key: apiKey
        },
        data: {
            requestType     : "VERIFY_EMAIL",
            idToken         : accessToken
        }
    };

    return await processRequest(options); //This is just to fire the request
}

注册后,立即将访问令牌传递给此方法,它会向注册用户发送邮件。

apiKey :在Firebase控制台的项目设置的“常规”标签中是否列出了“ Web API密钥” 访问令牌:当前用户的访问令牌(我在内部使用signup rest api,因此可以选择请求令牌作为响应)