1
votes

The use of email verification + email/password authentication doesn't quite work for services that absolutely need email verification before the user can begin using the service.

Let me explain with an example for Google sign in first.

First, the user signs into their Google account (say email is [email protected]), and authorizes your app. Then you create a credential using the tokens received through that, and exchange those tokens with Firebase to log the user into Firebase. The user needs to exist in Firebase for you to use Firebase' email verification service (because the only way to get info on whether an email is verified is to check the currentUser object in the client, so you need a logged in user to check if their email is verified. You can't call an Auth method with an email address to check if it's verified or not). So once you log the user into Firebase, you send them a verification link, and all is good. You can configure the view on your client by checking the user object for email verification. An important point to note here is that some other user who knows this user's email address cannot register using [email protected] on your service: this is because they need to sign into Google with that email to register.

Facebook is similar to Google sign-in in this regard.

However, for email/password, anyone can take someone else's email and create an account with it! And since you cannot send a verification link before the user is registered in Firebase, you're essentially letting anyone in the world "block" email addresses on your service. I was initially trying to ensure email verification before the email is registered into Firebase, but quickly realized that I need the user in Firebase to do any email verification.

Am I missing something, or is this the expected behavior? If this is really how it works, then I might just not allow email/password login in my app.

Side note: another idea I had was to do verification by sending them a 6-digit code, and maintain my own verification system in Firebase. But then I can't add any security rules to it, since any client without a logged in user would need access to it ==> potential system abuse.

Thanks in advance for attempting to read through the long explanation.

1
Am I missing something, or is this the expected behavior? No, you aren't missing anything. That's the expected behavioursudo_kaizen
You may have overlooked the sendSignInLinkToEmail in the Firebase guide. For sign-in to succeed, this email address must match the address to which the sign-in link was originally sent.Jay
That seems to be for signing in users using email links. My question is regarding sign in using email/passwords. The page you mentioned doesn't seem to have any security measures for email/password unfortunatelyuser1056585

1 Answers

1
votes

So even though an account can be created unverified, you can still block user access using security rules. The latter is what matters and controls access. Here is an example how you can do so with realtime database rules:

{
  "rules": {
    "users": {
      "$user": {
        ".read": "auth.token.email_verified == true && auth.uid === $user",
        ".write": "auth.token.email_verified == true && auth.uid === $user"
      }
    }
  }
}

You can also do this on your own if you are verifying the ID token on your server by parsing the token payload and inspecting the email_verified.

So even if the user account is created, unless the user is verified, they will not have access to your app/site data.