问题
I want to restrict the users to be able to sign in in my Firestore application using the specific gmail domain. I found the similar question here but that is totally different from the Firestore. So let me explain my requirement what I want.
Suppose one company called abc.com are using the gmail services and they have integrated their all email accounts to gmail. So they can use gmail email services using that account. So I want to restrict to users that only use the username@abc.com gmail account to login to my firestore app.
I have searched a lot but didn't found any documentation about this.
回答1:
There doesn't seem to be a solid Firestore solution for this but I have a compound solution:
- A security rule on the first data collection accessed, where I check the email domain
- A catchError on the data retrieval, where I check for error code 'permission-denied'
- An error handler that will call the authentication service and force a logout with a redirect to an unauthorized page.
Sorry about pasting snippets, but I couldn't get the formatter to format all the code.
My component code:
ngOnInit(): void {
this.leadsDataSubscription = this.leadService.getLeadsSnapshot()
.pipe(
catchError((e: any) => Observable.throw(this.errorHandler(e)))
)
.subscribe(data => {
this.leadsDataSource.data = data;
this.leadsDataSource.paginator = this.paginator;
this.leadsDataSource.sort = this.sort;
});
this.currentUser = this.authSvc.getCurrentUser();
}
private errorHandler(error: any) {
if (error.name === 'FirebaseError' && error.code === 'permission-denied') {
this.leadsDataSubscription.unsubscribe()
this.authSvc.logout('/unauthorized');
}
}
My service code
logout(redirectURL?: string) {
this.unsubscribe()
this.afAuth.auth.signOut()
.then(response => {
this.snackBar.open('Signed out');
this.router.navigate([redirectURL || '/']);
})
.catch(error => this.snackBar.open('Error signing out: ' + error));
}
And the Firestore rules:
match /leads/{document=**} {
allow read: if isAllowedDomain() && isSignedIn();
allow update: if isAllowedDomain() && isSignedIn() && canUpdate()
allow delete: if isAllowedDomain() && isSignedIn() && isCreator() && canWrite() || isGod()
allow create: if isAllowedDomain() && isSignedIn() && userExists();
}
function isAllowedDomain() {
return request.auth.token.email_verified == true &&
request.auth.token.email.matches(".*@workdomain.se") ||
request.auth.token.email.matches(".*@privatedomain.org")
}
回答2:
You cannot restrict domains in email authentication or gmail authentication. This is the trade off you have to make when using third party like Firebase solution for authentication.
In case of gmail auth on android what you can do is first read gmail accounts available on device and then only show accounts if the domain matches. This way you can at least restrict user on UI level to have certain domain.
BUT beware the user can still do another domain login since firebase allows all gmail accounts to use authentication. You are only restricting the UI not the system
来源:https://stackoverflow.com/questions/49985612/restrict-firestore-gmail-sign-in-to-specific-domain