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

Closed
arhmnsh opened this issue Jan 24, 2017 · 95 comments · May be fixed by #696
Closed

[Feature request] Disable new user signups #99

arhmnsh opened this issue Jan 24, 2017 · 95 comments · May be fixed by #696

Comments

@arhmnsh
Copy link

@arhmnsh arhmnsh 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
Copy link
Member

@bojeil-google bojeil-google 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.

Loading

@krisdev-pl
Copy link

@krisdev-pl krisdev-pl 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.

Loading

@krisdev-pl
Copy link

@krisdev-pl krisdev-pl 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

Loading

@arhmnsh
Copy link
Author

@arhmnsh arhmnsh 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 :)

Loading

@Splaktar
Copy link

@Splaktar Splaktar 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.

Loading

@krestaino
Copy link

@krestaino krestaino 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.

Loading

@Moonwalker7
Copy link

@Moonwalker7 Moonwalker7 commented Sep 27, 2017

Is this issue taken care in FirebaseUI version 2.3.0 ?

Loading

@rained23
Copy link

@rained23 rained23 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 ?

Loading

@bojeil-google
Copy link
Member

@bojeil-google bojeil-google 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.

Loading

@nicolasgarnier
Copy link
Member

@nicolasgarnier nicolasgarnier 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.

Loading

@bojeil-google
Copy link
Member

@bojeil-google bojeil-google commented Dec 18, 2017

Good suggestion @nicolasgarnier. I like that one.

Loading

@quincycs
Copy link

@quincycs quincycs 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.

Loading

@ralvs
Copy link

@ralvs ralvs 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.

Loading

@mesqueeb
Copy link
Contributor

@mesqueeb mesqueeb 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.

Loading

@rained23
Copy link

@rained23 rained23 commented Jan 27, 2018

Loading

@bojeil-google
Copy link
Member

@bojeil-google bojeil-google 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.

Loading

@mesqueeb
Copy link
Contributor

@mesqueeb mesqueeb 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?

Loading

@bojeil-google
Copy link
Member

@bojeil-google bojeil-google 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.

Loading

@Floo0S
Copy link

@Floo0S Floo0S commented Feb 1, 2018

Does anyone have a small code example for this workaround?

Loading

@mesqueeb
Copy link
Contributor

@mesqueeb mesqueeb 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.

Loading

@quincycs
Copy link

@quincycs quincycs 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.

Loading

@irmingard
Copy link

@irmingard irmingard 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?

Loading

@bojeil-google
Copy link
Member

@bojeil-google bojeil-google 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.

Loading

@Splaktar
Copy link

@Splaktar Splaktar 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.

Loading

@bojeil-google
Copy link
Member

@bojeil-google bojeil-google 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"
      }
  }
}

Loading

@ShaMan123
Copy link

@ShaMan123 ShaMan123 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

Loading

@mesqueeb
Copy link
Contributor

@mesqueeb mesqueeb 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?

Loading

@bojeil-google
Copy link
Member

@bojeil-google bojeil-google 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.

Loading

@JorgeHerreraU
Copy link

@JorgeHerreraU JorgeHerreraU 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.

Loading

@ykamal
Copy link

@ykamal ykamal commented Oct 7, 2019

Yeah Firebase, ya done mucked up. This is just bad. Over 75% of the apps I work on require internal registration and doesn't allow open registration. This makes Firebase completely useless to pretty much majority of my projects.

Loading

@Matesanz
Copy link

@Matesanz Matesanz commented Oct 10, 2019

It's been two and a half years now... is not going to be such an implementation?

Loading

@Splaktar
Copy link

@Splaktar Splaktar commented Oct 10, 2019

Yeah Firebase, ya done mucked up. This is just bad. Over 75% of the apps I work on require internal registration and doesn't allow open registration. This makes Firebase completely useless to pretty much majority of my projects.

@ykamal That's not quite accurate. It only makes you not able to use firebaseui-web, not Firebase itself. You can still use Firebase just fine by creating your own sign up and auth UI or using something like https://github.com/AnthonyNahas/ngx-auth-firebaseui.

Loading

@rynop
Copy link

@rynop rynop commented Oct 10, 2019

@Splaktar I don't use firebaseui-web, and from what I've seen, a user doing a social/google login against FBase that does not exist, will be created. The only hack/workaround that works for me is a firebase function like the one mentioned above that disables new user onCreate. FWIW here is FBase function I use (the one in the comment I link to did not work for me):

const functions = require('firebase-functions');
const admin = require("firebase-admin");
admin.initializeApp();

exports.blockSignup = functions.auth.user().onCreate(event => {
    console.log("event", event);

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

Loading

@Splaktar
Copy link

@Splaktar Splaktar commented Oct 10, 2019

@rynop that sounds like an issue that should be reported against the Firebase Admin SDK repo and not here in the firebaseui-web repo. I don't see an existing issue opened against the Admin SDK related to disabling new user sign up.

Loading

@tfesslerCWC
Copy link

@tfesslerCWC tfesslerCWC commented Oct 10, 2019

When adding a user, I initially add them to a firebase table then I create the user. i also have a function for user onCreate that checks the table for the user being created against the table of users. if the user isn't in the db, I don't delete the just created user.

The lookup could go against the db of users or a temporary queue, where the record is deleted after the lookup passes in onCreate.

Yeah.. It's a bass ackwards approach that works well in every instance I've used it. Once the curve of understanding to get around the problem is passed... it's smooth sailing.

Loading

@Jarrio
Copy link

@Jarrio Jarrio commented Jan 14, 2020

I would like to know the state of this issue? It is CLEARLY a wanted feature, why has it taken 3 years to not consider adding a simple toggle

if (toggled) {
   allowSignups();
} else {
   refuseFurtherSignups();
}

Sure this a bit of an oversimplification, but it really isn't that much more and if it is - at least communicate the internal issue so your users can try to relate to the primary concerns and would be more willing to compromise. As it stands this is just unnecessarily blown out of proportion.

Even outside of internal usage - alpha and beta tests are a thing for production purposes and controlling sign ups with what you intend to be your primary authentication methods just makes basic sense.

Loading

@jaunt
Copy link

@jaunt jaunt commented Feb 11, 2020

My desire has to do strictly with GUI/UX for users who are non technical. Security is not my issue.

  1. When I have sent them to a page to create an account, the widget should say "create an account", not "sign in". Or if I could hide that text, I could surround it by my own text.

  2. When a user accidentally mistypes their email, they sometimes blindly enter their first and last name and password, and don't even see the that the header changed to "create an account".

What I want:

  1. Option to hide the headings.
  2. Option to only sign in, or only create an account. I.e. say something like "account doesn't exist" if a user tries to sign in with a non existent email account. Or "this account already exists" for creation mode.

Loading

@antonbehaeghe
Copy link

@antonbehaeghe antonbehaeghe commented Feb 18, 2020

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.

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.
});

I have a cloud function that sets the claims when a new user is created, but how do I edit the claims? Can I do this through the Firebase Console? The Admin SDK is server-side only and I only have a client-side app...

Loading

@wisammechano
Copy link

@wisammechano wisammechano commented Mar 24, 2020

Please add a way to block new signups and have signups managed through the admin sdk

Loading

@chucklay
Copy link

@chucklay chucklay commented Apr 6, 2020

Adding another request to fix this. There needs to be an option that can be passed in to disable the sign-up auto-prompt.

Loading

@shaibruhis
Copy link

@shaibruhis shaibruhis commented Apr 6, 2020

Still waiting on a proper solution for this :/... Does anyone know if it's possible to log in via a curl command or something similar? That way I can make users in the firebase console and sign in through the curl command and not have to surface the UI at all.

Loading

@kimroen
Copy link

@kimroen kimroen commented Apr 24, 2020

Just to add our usecase to this:

We have a mobile app where users can create users. When the user is created, the mobile app also creates a document for them in firestore in the users collection using the same id so that we can store other data and relations.

Because this was a mobile-only app to start, the mobile client does all this.

Now, we're starting to introduce some web functionality as well. To not have to build everything all at once, we wanted to allow existing users to sign in with email and password and manage some of their data.

As far as I can tell from this thread, we actually won't be able to do this with firebaseUI-web, because the user will create a Firebase Auth user that doesn't have a linked document in users, and everything in our system assumes that this document will exist.

We are going to migrate over and allow the web to create users over time, but we were hoping to deploy parts of this functionality at a time.

Am I right in saying that we cannot do this using FirebaseUI, and we'll have to implement the sign-in UI ourselves?

Loading

@janswist
Copy link

@janswist janswist commented May 17, 2020

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.

It takes you over 3 years to implement simple solution and it's still not yet her. You're limiting people to much and actually not doing much with it. How many workaround do we have to make because you have some more important issues to deal with?

Loading

@yuchenshi
Copy link
Member

@yuchenshi yuchenshi commented Jul 6, 2020

FYI, this is still on our roadmap.

Loading

@pashaseliverstov
Copy link

@pashaseliverstov pashaseliverstov commented Jul 6, 2020

Loading

@yuchenshi
Copy link
Member

@yuchenshi yuchenshi commented Jul 6, 2020

Could you please raise up the priority for this issue.

One of our teams is actively working on a feature that will unblock this. While we cannot commit to an exact release date, I can assure you that this feature request is being prioritized.

EDIT: More accurate wording

Loading

@pashaseliverstov
Copy link

@pashaseliverstov pashaseliverstov commented Jul 6, 2020

Loading

@firebase firebase deleted a comment from nmhung1210 Jul 6, 2020
@firebase firebase locked as off-topic and limited conversation to collaborators Jul 6, 2020
@katowulf
Copy link
Member

@katowulf katowulf commented Jul 6, 2020

(Locked for being too heated. Eng team will continue to update as they make progress and may unlock in the future.)

Keep in mind that we prioritize work based on what is most useful for our platform's target use cases. We can't solve every use case for every developer. Anyone developing an app or platform at scale understands that carefully choosing priorities and picking the best tradeoffs is a difficult, slow, and necessary process. This is one open source repo out of several, and we support 8 million developers. Less than a hundred requesting a feature doesn't translate to immediate changes to the product. Please keep the comments civil and constructive, and try to keep the bigger picture in mind.

Loading

@bojeil-google
Copy link
Member

@bojeil-google bojeil-google commented Mar 9, 2021

Support for disabling new user sign up has been added in v4.8.0.
Details on how to use this are provided here.

Note that the recommendation is to use this with server side enforcement via either blocking functions or disabling new user sign up to prevent malicious users from bypassing the UI.

Loading

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.