Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature request] Disable new user signups #99

Open
arhmnsh opened this issue Jan 24, 2017 · 75 comments

Comments

@arhmnsh
Copy link

commented Jan 24, 2017

When a new user types their email address in the signin form, it shows the new signup form.
How can I disable this?
I just want the users who I have already created from firebase console to access my app.

@bojeil-google

This comment has been minimized.

Copy link
Member

commented Jan 24, 2017

Hey @arhmnsh, that is currently not supported. It is not a common feature. In fact, it is hard to block that for OAuth sign in as you can't tell if the account is already created or not before launching the sign in to that provider. I am assuming you are using password sign-in in your case.

@krisdev-pl

This comment has been minimized.

Copy link

commented Feb 7, 2017

@bojeil-google but it's implemented in FirebaseUI for Android and will be shipped in version 1.2.0.
Here's the link: firebase/FirebaseUI-Android#530
FirebaseUI for Android and iOS have feature parity so I assume it'll show in iOS as well.
It would be useful for users who have mobile app for their web app.

@krisdev-pl

This comment has been minimized.

Copy link

commented Feb 23, 2017

FirebaseUI 1.2.0 is already released, and mentioned functionality is present as per milestone: https://github.com/firebase/FirebaseUI-Android/milestone/13?closed=1
and issue: firebase/FirebaseUI-Android#530

@arhmnsh

This comment has been minimized.

Copy link
Author

commented Feb 26, 2017

@krisdev-pl hi! Thanks for the info. but this issue is to restrict new user signups for firebaseui-web, not for mobile apps :)

@Splaktar

This comment has been minimized.

Copy link

commented Apr 18, 2017

I'm trying to use firebaseui-web on a project atm and we're using EmailPassword Auth only with AccountChooser.com disabled. We need the ability to hide or disable users creating accounts.

Our requirements are that either we need to send them a special link for them to create an account or we need to manually add their account before they login.

Currently there does not seem to be a simple way to disable account creation in firebaseui-web w/o forking the project. Please add an option to enable/disable account creation when using EmailPassword Auth.

@krestaino

This comment has been minimized.

Copy link

commented Aug 3, 2017

Would really love to see an option to disable new user sign-ups. I built a tool for internal use only, and there's no reason for anyone to ever sign-up. It's just a small pool of users who need admin access that I'd like to manage within the Firebase console.

@Moonwalker7

This comment has been minimized.

Copy link

commented Sep 27, 2017

Is this issue taken care in FirebaseUI version 2.3.0 ?

@rained23

This comment has been minimized.

Copy link

commented Dec 16, 2017

I am trying to disable sign up too because this make request.auth != null unusable for firestore, because everyone can just signing up an account and have the read access to the database.

one more thing is someone can spam a fake account on our authentication and how to prevent that ?

@bojeil-google

This comment has been minimized.

Copy link
Member

commented Dec 18, 2017

@rained23 your question seems better suited for stackoverflow.
You can't disable sign up by using Firebase rules as it will also block users that you sign up on your end too and who later sign in.

FirebaseUI has plans to disable sign up but it may lack teeth as this seems like a feature better enforced on the Firebase Auth backend first. You are welcome to file an official request for it: https://firebase.google.com/support/ For now, we plan to return the isNewUser boolean on sign in via FirebaseUI. That will tell you if a user is new or existing. You could build on that but only enforce it on the client.

When you refer to fake account, do you mean fake emails? If so, you should send an email verification after FirebaseUI sign in and then monitor your users and delete those who do not verify after a while. Firebase Admin SDK provides tools to look up all your users and delete them if you want.

@nicolasgarnier

This comment has been minimized.

Copy link
Member

commented Dec 18, 2017

Possibly this could be done with Custom claims: https://firebase.google.com/docs/auth/admin/custom-claims

You would have a server (you could use Cloud Functions with a user().onCreate() trigger or an HTTP trigger if you want to do this in a sync'ed way) that checks if the user is allowed to signup and add a custom claim to the user. For instance something such as allowed = true or false. On the client you could wait for the server to set this custom claim for the user, refresh the user and check if it is true or false and display the appropriate UI.

You can use the custom claims in the security rules to allow only users with the allowed custom claim to read data.

@bojeil-google

This comment has been minimized.

Copy link
Member

commented Dec 18, 2017

Good suggestion @nicolasgarnier. I like that one.

@quincycs

This comment has been minimized.

Copy link

commented Jan 17, 2018

My use case: we want signup to be a back office process after contracts are signed. We don’t want sign up to be easy.

Due to this issue we are going to implement our UI in our own way via using the REST api.

@ralvs

This comment has been minimized.

Copy link

commented Jan 22, 2018

I think its a very useful feature for firebaseui-web!

For now, I'm using the workaround for auto disable new users using cloud functions.

const admin = require("firebase-admin");

exports.blockSignup = functions.auth.user().onCreate(event => {
  return admin.auth().updateUser(event.data.uid, { disabled: true })
	.then(userRecord => console.log("Auto blocked user", userRecord.toJSON()))
	.catch(error => console.log("Error auto blocking:", error));
});

Remembering that this function is also fired when you create users using the firebase web console. So you have to create, await the function, then enable the user.

@mesqueeb

This comment has been minimized.

Copy link
Contributor

commented Jan 27, 2018

Since this is still open:
I also require google provider login but only for users who already exist. Block any attempts to login with a new google account that's not yet in my firebase user list.

@rained23

This comment has been minimized.

Copy link

commented Jan 27, 2018

@bojeil-google

This comment has been minimized.

Copy link
Member

commented Jan 28, 2018

Hey @rained23, we should definitely support this use case and it is on our list.

I still think that @nicolasgarnier's solution is actually very feasible and doesn't require much work.
The only additional work you are doing here is setting the custom attribute when creating the account (to differentiate users your admins created) and adding a check in your Firebase security rules or ID token verification for that attribute.

Anyway, you can also submit an official request for this feature via Firebase support.

@mesqueeb

This comment has been minimized.

Copy link
Contributor

commented Jan 28, 2018

@nicolasgarnier

For instance something such as allowed = true or false. On the client you could wait for the server to set this custom claim for the user, refresh the user and check if it is true or false and display the appropriate UI.

Do you mean if you retrieve the user from the server and then on the client side check for the value allowed and then display the UI according to that?

Since you have to check for the value on the browser side, there no stopping people from editing your front-end code and making allowed true just before it gets checked.

Am I correct and could this pose a security issue?
Or is there a safe way where the users on the front end can't mess with the values that came from the server?

@bojeil-google

This comment has been minimized.

Copy link
Member

commented Jan 28, 2018

If you want to disable sign ups from the client, you would basically use the Admin SDK to create the user and set the custom attribute allowed on that user. Doing this via the Admin SDK ensures that only an admin can create the user.

In your Firebase security rules or if you are using your own server and verifying the ID token on your own, you would only allow users with that custom attribute to access data.

This has to be enforced on the server/security rules. Client side checks are helpful to show the appropriate UI and messaging to the user. They should not be relied upon. This is helpful if a user tries to sign up and the attribute is not there. You could also check isNewUser is true in UserCredential when signing in with the client and show the error message. Even if the user modifies the client, they still won't be able to access the data as your server will enforce that check.

@Floo0S

This comment has been minimized.

Copy link

commented Feb 1, 2018

Does anyone have a small code example for this workaround?

@mesqueeb

This comment has been minimized.

Copy link
Contributor

commented Feb 1, 2018

If there could be a hook server side on login (even through google provider) I could set up:

If (!allowedUsersEmailArray.contains(user.email)) user.signOut()

I know this is front end code but that's the gist of what I'd want to be able to do server side with the great Firebase.

@quincycs

This comment has been minimized.

Copy link

commented Feb 1, 2018

I’ve got my own backend with its additional role checks already. If they can hack my app and still signup with Firebase, they still won’t be able to actually login to my app because I check for roles in my custom backend on every web api call.

@irmingard

This comment has been minimized.

Copy link

commented Feb 2, 2018

Here's my current setup, let me know if I've left open a loophole with that:

I have the following rules:
{
"rules": {
".read" : "auth != null && root.child('allowedusers').hasChild(auth.uid)",
".write" : "auth != null && root.child('allowedusers').hasChild(auth.uid)"
}
}

And as you can guess from above, I have an "allowedusers" object in my realtime database.

The behavior is the following:
While anyone is still welcome to try and login, they will be redirected to a denied.html page if their uid could not be found in the "allowedusers" object. When you want to add a new "alloweduser" retrospectively, you just have to add their uid to the "allowedusers" object.

Thoughts?

@bojeil-google

This comment has been minimized.

Copy link
Member

commented Feb 2, 2018

You are better off just relying on custom claims:

".read" : "$user_id === auth.uid && auth.token.alloweduser === true",
".write" : "$user_id === auth.uid && auth.token.alloweduser === true"

This is way more efficient than having to lookup your allowed users on each request, especially if you have a huge list of users.

@Splaktar

This comment has been minimized.

Copy link

commented Feb 2, 2018

@bojeil-google do you have a link where we can read about how to set custom claims like auth.token.alloweduser when using Firebase? I have been doing something similar to what @irmingard posted.

@bojeil-google

This comment has been minimized.

Copy link
Member

commented Feb 2, 2018

After you create the user. you would set the custom claim on that user via Admin SDK:

admin.auth().setCustomUserClaims(uid, {alloweduser: true}).then(() => {
  // The new custom claims will propagate to the user's ID token the
  // next time a new one is issued. Since this is created before the user signs in,
  // then when the user signs in, they will have that claim directly.
});

You can then enforce access via security rules without having to do any lookup:

{
  "rules": {
    "data": {
      "$user_id": {
        ".read" : "$user_id === auth.uid && auth.token.alloweduser === true",
        ".write" : "$user_id === auth.uid && auth.token.alloweduser === true"
      }
  }
}
@ShaMan123

This comment has been minimized.

Copy link

commented Feb 17, 2018

Thanks for this thread! Helped me a lot.
My contribution:
Combining custom claims with a rewrite to cloud functions called from FirebaseUI => uiConfig => callbacks => signInSuccess.

My Gist

documentation:
custom claims
rewrites
FirebaseUI => callback => signInSuccess

@mesqueeb

This comment has been minimized.

Copy link
Contributor

commented Feb 18, 2018

@bojeil-google i'm still confused about the security. Even if the Admin can only set a custom claim through admin.auth().setCustomUserClaims can't the user just set {allowedUser: true} on their user object and get inside the database?

@bojeil-google

This comment has been minimized.

Copy link
Member

commented Feb 18, 2018

This is stored in the ID token claims. The ID token cannot be manipulated without knowing the project's private key. Nothing on the client should be trusted. The ID token is the only source of truth.

@JorgeHerreraU

This comment has been minimized.

Copy link

commented Feb 19, 2018

How would I restrict sign up if I'm just using the web hosting service of firebase and not a database. It would be great to have this feature available within the firebase console.

@ajCastiglione

This comment has been minimized.

Copy link

commented Jul 8, 2018

Any news on this? I'm trying to build an app with firebase but there isn't an easy way to prevent random users from signing up without doing some hacky workaround.

@nietsmmar

This comment has been minimized.

Copy link

commented Aug 22, 2018

I would also love to have this feature. I've build an app, where users should be able to sign-up in my android-app but in the webapp-part they should only be able to sign-in, not sign-up.

@nicolasgarnier nicolasgarnier changed the title Disable new user signups Feature request: Disable new user signups Aug 30, 2018

@nicolasgarnier nicolasgarnier changed the title Feature request: Disable new user signups [Feature request] Disable new user signups Aug 31, 2018

@dandv

This comment has been minimized.

Copy link

commented Sep 24, 2018

I will repeat this once again. This is not the correct way to do this. The Auth backend needs to throw an error on creation via client SDK which firebaseUI catches.

Agree, but I think @boonyasukd means something different: we would simply like the auth web UI to be configurable to only show elements related to signing in - a matter of friendly UX, rather than security. Much like the Okta live widget but without the "Sign up" link at the bottom.

@arthabus

This comment has been minimized.

Copy link

commented Sep 26, 2018

@dandv As long as the issue #499 I've rise was marked as duplicate to this one, I'd add to your last comment that having "Sign up" link would be very useful as in our scenario we still need to provide both sign in and sign up flows but they shouldn't switch automatically as this leads to confusion.

@dandv

This comment has been minimized.

Copy link

commented Sep 26, 2018

Agree, I find the auto-switching confusing as well.

Plus, what if a user knows they've signed up already, but wants to sign up with a new account?

@pashaseliverstov

This comment has been minimized.

Copy link

commented Feb 5, 2019

This issue is opened for 2 years now!
@bojeil-google please add configuration parameter to disable self sign ups.
It is real problem for the end users. They keep using new email addresses and get disappointed after login with new email.
It would be also great to have ability to pre-populate email address at sign-in from the link the users receive in email.
At the moment about 20% of my users experience confusion at sign in because they keep entering new email addresses.

@thangbn

This comment has been minimized.

Copy link

commented Feb 9, 2019

this really sucks, I'm evaluating Firebase and disappointed by the lack of customisability. Considering not using Firebase.

@bdykzeul

This comment has been minimized.

Copy link

commented Feb 10, 2019

this really sucks, I'm evaluating Firebase and disappointed by the lack of customisability. Considering not using Firebase.

Just build your own UI and use the firebase auth API. you don't have to use the firebase-ui; it's optional

@dandv

This comment has been minimized.

Copy link

commented Feb 10, 2019

@bdykzeul: do you know of projects that have done this? I'm curious how fast the login is, because with firebase-ui, it's weirdly slow.

@Splaktar

This comment has been minimized.

Copy link

commented Feb 11, 2019

@dandv I have done it for the majority of my projects. It's faster, lighter on bundle size, and much more flexible and customizable.

@W357

This comment has been minimized.

Copy link

commented Mar 16, 2019

There should be an option to make signup an admin feature. Its a no go for business applications that anyone knowing the (not secret) api key can create user using the rest api.

@geekflyer

This comment has been minimized.

Copy link

commented Mar 18, 2019

Google released recently Cloud Identity for Customers and Partners (CICP) https://cloud.google.com/identity-cp/ which is based on Firebase Auth.

The lack of Firebase UI's ability to actually restrict sign up (in non confusing manner) to Customers and Partners makes firebase UI a non-starter for CICP's target audience (which in my understanding includes B2B / Enterprise apps).
Please consider adding this feature soon.

Since we're pretty much a google shop I wanted to like CICP but it seems in the meantime we gotta go with Auth0 which fully supports disabling of sign ups for email / password users.

@Splaktar

This comment has been minimized.

Copy link

commented Mar 19, 2019

I just found https://github.com/AnthonyNahas/ngx-auth-firebaseui recently and it supports disabling user registration. The one thing that it doesn't support is Phone Auth. So as long as you are using Angular and aren't using Phone Auth, that may be a valid alternative for your project since it doesn't look like this issue will be addressed soon.

@ep1703

This comment has been minimized.

Copy link

commented Apr 18, 2019

when new user create account cloud functions will trigger and admin sdk can make that user account disable, so it means it is possible to disable every new account
exports.BlockNewUser = functions.auth.user().onCreate((user) => { return adminFire.auth().updateUser(user.uid, { disabled: true }).then(function(userRecord) { // See the UserRecord reference doc for the contents of userRecord. console.log('Successfully updated user', userRecord.toJSON()); return true; }) .catch(function(error) { console.log('Error updating user:', error); }); });

@nietsmmar

This comment has been minimized.

Copy link

commented Apr 18, 2019

when new user create account cloud functions will trigger and admin sdk can make that user account disable, so it means it is possible to disable every new account

yes but for example in my case I got an app for phones and another app for web. One is for users one for customers. The web-app should only offer login and no sign up. The mobile app should offer both.

@cdock1029

This comment has been minimized.

Copy link

commented Apr 19, 2019

make that user account disable

Or just delete the user if you have all the users you want created.

export const preventUserCreation = functions.auth.user().onCreate((user, _) => {
  return admin.auth().deleteUser(user.uid)
})

Mix with whitelist strategy to allow for future dynamic checks for new users, that you can manage in the console.

I got an app for phones and another app for web

If it's 1 Firebase project and 1 pool of auth accounts, then what is the difference if they sign up through the admin interface, given the admin privileges must be granted some other way anyways (not simply by signing up)?

You could whitelist emails in a protected collection, then check list upon user creation to see if admin role should be granted, through customs claims for example.

export const checkAdmin = functions.auth.user().onCreate(async (user, _) => {
  const whiteListRef = admin
    .firestore()
    .collection('whitelist')
    .doc(user.email)
  const snap = await whiteListRef.get()
  if (!snap.exists) {
    return
  }
  await admin.auth().setCustomUserClaims(user.uid, { admin: true })
  console.log(`created user=[${user.uid}] set as admin`)
  return whiteListRef.delete()
})

If it's 2 projects then just use the delete user function for the admin project.

@sperochon

This comment has been minimized.

Copy link

commented Apr 25, 2019

Hello,

I have a web app with just email/password login using firebaseui. As a lot of people here, I do not want that new users can sign up themselves. I only want that only already existing users that I created myself can signed in.
So, here is the solution I've just implemented tonight. It can't answered to every case but I hope it will help someone...

This is a 100% web client solution. No firebase function involved. So, to be 100% proof, you need to implement some security rules on server side too... as you already have should done with the normal firebaseui usage...

Here is what to do :

  1. Clone or download the source code of firebaseui-web
    https://github.com/firebase/firebaseui-web
  2. Do 'Developer Setup' (only 'Dependencies' and 'Building FirebaseUI' ; no need of Python or demo app) as described here : https://github.com/firebase/firebaseui-web#developer-setup

then choose one of the 2 solutions 3a) or 3b) (or try both) :

3a) Keep the same first sign-in page as usual
Open the file javascript/widgets/handler/common.js and replace the content of first 'if' of function 'firebaseui.auth.widget.handler.common.handleSignInFetchSignInMethodsForEmail' with

if (!signInMethods.length && app.getConfig().isEmailPasswordSignInAllowed()) {
    // Account does not exist and password sign-in method is enabled. Go back to
    // sign in with error message.
    var errorMessage =
      firebaseui.auth.widget.handler.common.getErrorMessage({'code':'auth/user-not-found'});
    firebaseui.auth.widget.handler.handle(
      firebaseui.auth.widget.HandlerName.SIGN_IN,
      app,
      container,
      email,
      errorMessage);
} else ...

or

3b) First sign in page is directly the page which asks login AND password at the same time :
Open the file javascript/widgets/handler/common.js and replace the content of first 'if' of function 'firebaseui.auth.widget.handler.common.handleSignInStart' with :

if (firebaseui.auth.widget.handler.common.isPasswordProviderOnly(app)) {
    firebaseui.auth.widget.handler.handle(
        firebaseui.auth.widget.HandlerName.PASSWORD_SIGN_IN,
        app,
        container,
        opt_email,
        opt_infoBarMessage);
} else ...

build, then test the resulting 'firebaseui.js' ;-)

As a bonus, you can even change titles or messages in translations of firebase-ui :-)

@tfesslerCWC

This comment has been minimized.

Copy link

commented May 18, 2019

Google released recently Cloud Identity for Customers and Partners (CICP) https://cloud.google.com/identity-cp/ which is based on Firebase Auth.

The lack of Firebase UI's ability to actually restrict sign up (in non confusing manner) to Customers and Partners makes firebase UI a non-starter for CICP's target audience (which in my understanding includes B2B / Enterprise apps).
Please consider adding this feature soon.

Since we're pretty much a google shop I wanted to like CICP but it seems in the meantime we gotta go with Auth0 which fully supports disabling of sign ups for email / password users.

I couldn't agree MORE!

Come on team Firebase.... This VERY relevant for Enterprise customers using the Firebase platform for consumer facing mobile applications who need Admin consoles to support the Firebase Architecture..

@bojeil-google

This comment has been minimized.

Copy link
Member

commented May 20, 2019

We remain committed to supporting this feature (the secure way by disabling it server side first, and whose implementation is already in the works) and many more exciting features that are on our roadmap, some of which we already announced, including support for blocking (synchronous) functions and multi-factor authentication a couple of weeks ago. FirebaseUI will support both, Firebase Auth and Google Cloud Identity Platform.

@CraftedPvP

This comment has been minimized.

Copy link

commented Jul 10, 2019

Can't we just allow a 0 sign-up quota? the minimum is set to 1 for some reason. Setting it to zero could be also one of the solutions to solve this issue.

@nietsmmar

This comment has been minimized.

Copy link

commented Jul 10, 2019

Can't we just allow a 0 sign-up quota? the minimum is set to 1 for some reason. Setting it to zero could be also one of the solutions to solve this issue.

This wouldn't be a complete solution, as in my case I want to disable sign-up in my web app but not in my android app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.