Firebase 身份验证电子邮件 - 防止虚假/无效帐户

问题描述 投票:0回答:2

我正在使用 Firebase 身份验证电子邮件帐户将用户注册到网站。 我最近注意到以下情况。

  1. 用户使用有效的电子邮件地址注册,然后从不验证 电子邮件地址
  2. 用户尝试使用虚假电子邮件地址注册

对于第一种情况,我们可以搜索一段时间内所有未验证的账户并将其删除。

admin.auth().getUser(uid).then(user => {
  const creationTime = user.metadata.creationTime
  const isVerified = user.emailVerified
  const lastSignInTime = user.lastSignInTime
  if(!isVerified){
    // Process and delete unverified accounts after x days
    ...
  }
})

我们如何处理电子邮件地址虚假或拼写错误的帐户?我在 firebase.User 对象上没有看到任何指示无效电子邮件地址的属性。但是,对于使用无效电子邮件地址注册的每个用户,我们确实会收到邮件发送失败消息 - 这不足以自动清除虚假/无效帐户。

防止虚假注册的最佳做法是什么?

亲切的问候/K

security firebase-authentication
2个回答
1
投票

您无法阻止某人使用任何看起来像电子邮件地址的字符串,并且系统无法告诉您验证电子邮件已成功发送。

处理此问题的通常方法是为每个用户帐户创建一些数据库记录来跟踪其验证状态。您可以查询数据库以找出哪些用户在一段时间后尚未验证。您的应用程序应该从用户发送您的后端 ID 令牌,可用于检查它们是否经过验证,如果是,则更新数据库以表明它已发生。

参见:


1
投票

这就是我想出的用于清除未经验证的帐户的代码。 可能不是最优雅的解决方案,但可行。

exports.scheduledUserCleanup = functions
.region('europe-west1')
.pubsub
.schedule('0 3 * * *')
.timeZone('Europe/Stockholm')
.onRun(async (event) => {
  const today = moment()
  const inactivityThresholdDays = 7 //Get purge threshold days

  let myPromises = [] //Collect all promises to carry out 

  //Search for users that have NOT validated email
  database.ref('user-signups').once('value', (usersSnapshots) => {
    usersSnapshots.forEach((snapshot) => {
      const uid = snapshot.key

      // Get user from firebase auth
      admin.auth().getUser(uid)
      .then((firebaseAuthUser) => {
        const creationTimeStr = firebaseAuthUser.metadata.creationTime
        const isVerified = firebaseAuthUser.emailVerified
        const lastSignInTimeStr = firebaseAuthUser.metadata.lastSignInTime
        const neverSignedIn = (creationTimeStr === lastSignInTimeStr) ? true : false

        if(!isVerified && neverSignedIn){
          // Process and delete unverified accounts after 7 days
          const creationTime = moment(creationTimeStr)
          const daysSinceCreation = today.diff(creationTime, 'days')

          if(daysSinceCreation > inactivityThresholdDays){
            console.log('Remove user from db and Firebase auth', uid)
            myPromises.push( admin.auth().deleteUser(firebaseAuthUser.uid) )
            myPromises.push( database.ref(`user-signups/${uid}`).remove() )
          }else{
            console.log(`Keep for ${inactivityThresholdDays} days before deleting`, uid)
          }
        }
        return true
      })
      .catch((error) => {
        // Remove if not found in Firebase Auth
        const notFoundInFirebaseAuth = (error.code) ? error.code === 'auth/user-not-found' : false
        if(notFoundInFirebaseAuth){
          console.log('Remove user from db', uid)
          myPromises.push( database.ref(`user-signups/${uid}`).remove() )
        }
        return false
      })
    })
  })

  // Execute promises
  return Promise.all(myPromises)
  .then(() => Promise.resolve(true))
  .catch((err) => {
    console.error('Error', err)
    return Promise.reject(err)
  })
})
© www.soinside.com 2019 - 2024. All rights reserved.