Search code examples
firebasefirebase-authenticationangularfire

Prevent user account creation with sign in by email in firestore


I have setup a passwordless login using firebase sign in with email link. Everything is working as expected, however when the user receives the email and clicks the link to login they are automatically created as a registered user.

https://firebase.google.com/docs/auth/web/email-link-auth

After a user signs in for the first time, a new user account is created and linked to the credentials...

This means anyone who makes a request in the login screen will get an email and get access to the site.

I am not sure if there is any configuration or setup that i need to complete in order to require that the user requesting the signup link are only checked against the users that are registered.

Something like

 firebase.auth().sendLoginLinkToEmail(email,{url:...,handleCodeInApp:true}).then(() =>{
    ....
  }, error =>{
     // return if not an authenticated user
  })

And if the email is not registered then it returns an error.

The idea is to have an administrator that creates users and then those created users just login with an email link ( no password )

Is this possible? To prevent firebase from creating an account with.signInWithEmailLink() ?


Solution

  • Passwordless email sign in allows the user to prove they have access to a certain mail box. It does inherently do nothing more than that. Once the user clicks the link, they are authenticated. Beyond enabling/disabling the entire sign-in provider, you cannot control who can sign-in/authenticate.

    After that it is up to your application to determine what this user is allowed to do. This is a separate step, typically called authorization.

    Firebase Authentication takes (as its name implies) care of authentication only. You will have to handle authorization elsewhere, depending on what services you provide the users access to.

    What makes an email "registered" in your app? I.e. where does the admin create those users? For example, if you store the users in the Cloud Firestore in a collection allowed_users, with documents like this:

    allowed_users: // collection
      "arkade@domain,com": { ... } // document
      "puf@domain,com": { ... } // document
    

    Now you can limit that only allowed users can access other data with Firestore's server-side security rules. Say you have a collection of posts, you can allow only these users to read posts with:

    service cloud.firestore {
      match /databases/{database}/documents {
        match /posts/{post} {
          // Make sure a 'allowed_users' document exists for the requesting user before
          // allowing any reads from the 'posts' collection
          allow read: if exists(/databases/$(database)/documents/allowed_users/$(request.auth.email))
      }
    }
    

    The syntax is a bit long, but your can see that is only allows the reading of a post if the current user's email address (request.auth.email) exists as a document in allowed_users.

    In rules version 2 of the Firestore rules, you access the current user's email address a little differently. You can do it via request.auth.token.email. The example below also shows how you can get a boolean property in the current user's document, if you identify that user by email:

    allow write: if get(/databases/$(database)/documents/users/$(request.auth.token.email)).data.admin == true;