What is the best way to prevent users from using an email address that does not end in @mycompany.com from logging in to our internal app through Firebase/Google auth?
package.json dependencies
"dependencies": {
"create-react-class": "^15.6.0", /* Ignore this */
"firebase": "^4.2.0",
"react": "16.0.0-alpha.12",
"react-native": "0.47.1",
"react-native-app-intro": "^1.1.5",
"react-native-google-signin": "^0.11.0",
"react-native-linear-gradient": "^2.2.0",
"react-navigation": "^1.0.0-beta.12"
}
android/settings.gradle
rootProject.name = '[My Project Name]'
include ':react-native-google-signin'
project(':react-native-google-signin').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-google-signin/android')
include ':react-native-linear-gradient'
project(':react-native-linear-gradient').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-linear-gradient/android')
include ':app', ':[Internal Android SDK]'
android/build.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.google.gms:google-services:3.0.0'
}
}
allprojects {
repositories {
mavenLocal()
jcenter()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
}
}
ext {
compileSdkVersion = 26
buildToolsVersion = "26.0.1"
}
subprojects { subproject ->
afterEvaluate{
if((subproject.plugins.hasPlugin('android') || subproject.plugins.hasPlugin('android-library'))) {
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
}
}
}
}
android/app/build.gradle
apply plugin: "com.android.application"
[...]
dependencies {
compile(project(":react-native-google-signin")){
exclude group: "com.google.android.gms" // very important
}
compile project(':react-native-linear-gradient')
compile project(':[Internal Android SDK]')
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:26.0.0-alpha1'
compile 'com.facebook.react:react-native:+'
compile 'com.facebook.fresco:animated-gif:1.0.1'
compile 'com.google.android.gms:play-services-auth:10.0.1'
compile 'com.google.firebase:firebase-messaging:10.0.1'
}
[...]
apply plugin: 'com.google.gms.google-services'
Current folder structure:
> app
> components [...]
> config [...]
> screens
HomeScreen.js
LoginScreen.js
[...]
> styles [...]
router.js (just a simple StackNavigator setup from react-navigation)
> assets
> fonts [...]
> img [...]
> node_modules [...]
index.android.js
index.ios.js
package.json
[...]
LoginScreen.js (This is a work in progress)
import React, { Component } from 'react';
import { Alert, Button, Image, Text, View } from 'react-native';
import {GoogleSignin, GoogleSigninButton} from 'react-native-google-signin';
export default class LoginScreen extends Component{
constructor(props){
super(props);
this.state = {
user: null
}
}
componentDidMount() {
this._setupGoogleSignin().then(() => console.log('Mounted & Google setup complete.'));
}
async _setupGoogleSignin() {
try {
await GoogleSignin.hasPlayServices({ autoResolve: true });
await GoogleSignin.configure({
hostedDomain: 'mycompany.com' //doesn't do anything
});
const user = await GoogleSignin.currentUserAsync();
console.log('User: ',user);
this.setState({user});
}
catch(err) {
console.log("Play services error", err.code, err.message);
}
}
_signIn() {
GoogleSignin.signIn()
.then((user) => {
console.log('User: ',user);
this.setState({user: user});
})
.catch((err) => {
console.log('WRONG SIGNIN', err);
})
.done();
}
_signOut() {
GoogleSignin.revokeAccess().then(() => GoogleSignin.signOut()).then(() => {
this.setState({user: null});
})
.done();
}
render(){
if (!this.state.user){
return (
<View style={{flex: 1}}>
<View style={{flex: 1.5, alignItems: 'center', justifyContent: 'center', marginTop: 40}}>
<Image
style={{width: 156, height: 156, resizeMode: 'contain'}}
source={require('../../assets/img/google_logo1600.png')} />
<Text style={{fontSize: 32, fontWeight: 'bold'}}>
Google Identity
</Text>
<Text style={[{fontSize: 15, paddingTop: 5}]}>
To continue, please sign-in.
</Text>
</View>
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center', marginBottom: 40}}>
<GoogleSigninButton
style={{width: 312, height: 48}}
size={GoogleSigninButton.Size.Wide}
color={GoogleSigninButton.Color.Light}
onPress={() => this._signIn()}/>
</View>
</View>
);
} else {
return (
<View style={{flex: 1}}>
<View style={{flex: 1.5, alignItems: 'center', justifyContent: 'center', marginTop: 40}}>
<Image
style={{width: 156, height: 156, resizeMode: 'contain'}}
source={require('../../assets/img/google_logo1600.png')} />
<Text style={{fontSize: 32, fontWeight: 'bold'}}>
Google Identity
</Text>
<Text style={[{fontSize: 15, paddingTop: 5}]}>
To continue, please sign-in.
</Text>
</View>
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center', marginBottom: 40}}>
<Button style={{width: 312, height: 48, backgroundColor: '#4385F2', color: 'white'}} title="Log Out" onPress={() => this._signOut()} />
</View>
</View>
)
}
}
}
If there's a better way to do this, I'm all ears. Thanks!
There is no way to limit who can authenticate with the default Firebase Authentication Google provider. But all the user does by signing in is authenticating themselves: "I am Frank van Puffelen and here's the proof".
You can restrict what resources users have access to. For example for the Firebase Database you can use its server-side security rules to determine what each user is authorized to access. Here you can limit access to users from a specific domain.
Also see:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With