草庐IT

android - 如何在 React Native 中限制谷歌登录到我公司的电子邮件域 (@company.com)?

coder 2023-11-27 原文

问题

防止用户使用不以 @mycompany.com 结尾的电子邮件地址通过 Firebase/Google 身份验证登录我们的内部应用程序的最佳方法是什么?

目标

  • 防止用户使用错误的电子邮件登录应用
  • 获取用户的公司电子邮件地址并将其用于其他地方的身份验证(即从内部网站提取数据)

约束

  • 我正在使用 react-native init,因为我必须使用我们公司的原生 SDK 模块来实现
  • 最好使用 Firebase 的解决方案,因为我们已经将其与所述原生 SDK 模块一起用于 FCM/推送通知。

研究成果

  • 我看到 react-native-google-signin 有一个“hostedDomain”选项,但它似乎没有做任何事情。我不确定如何使用它,也没有文档或很好的使用示例。有一个功能请求 here但我只能找到这些。
  • 我看到有一个类似的 repo,react-native-google-sign-in,但它没有提供关于这个主题的更多信息。
  • 我在某处读到,我可能认为这一切都是错误的,身份验证不能限制电子邮件地址(?),但我可以限制谁可以使用所述电子邮件地址访问信息。这对我没有帮助,因为我们现在没有使用 Firebase 的数据库做任何事情。我需要一种方法来引导用户使用他们公司的电子邮件登录。
  • This person seemed to have a similar issue并找到了护照的解决方案,但我不知道如何将其应用到我的用例中。

设置

  • IntelliJ 旗舰版 2017.2.2
  • React Native 0.47.1(使用 react-native init,而不是 CRNA 或 expo,因为我需要与原生 SDK 模块集成)
  • 来自 Firebase 的 google-services.json 存在于 android/app 文件夹中

安卓设置

package.json 依赖

"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'

React Native 设置

当前文件夹结构:

> 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(这是一项正在进行的工作)

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

    }
}

如果有更好的方法来做到这一点,我会洗耳恭听。谢谢!

最佳答案

无法限制谁可以使用默认的 Firebase 身份验证 Google 提供程序进行身份验证。但是用户通过登录所做的所有事情都是对自己进行身份验证:“我是 Frank van Puffelen,这就是证据”。

您可以限制用户可以访问的资源。例如 Firebase Database you can use its server-side security rules以确定每个用户有权访问的内容。在这里你可以limit access to users from a specific domain .

另见:

关于android - 如何在 React Native 中限制谷歌登录到我公司的电子邮件域 (@company.com)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45739994/

有关android - 如何在 React Native 中限制谷歌登录到我公司的电子邮件域 (@company.com)?的更多相关文章

  1. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  2. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  3. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  4. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  5. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  6. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

    我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"

  7. ruby - 如何在 Lion 上安装 Xcode 4.6,需要用 RVM 升级 ruby - 2

    我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121

  8. ruby-on-rails - 如何在 ruby​​ 交互式 shell 中有多行? - 2

    这可能是个愚蠢的问题。但是,我是一个新手......你怎么能在交互式ruby​​shell中有多行代码?好像你只能有一条长线。按回车键运行代码。无论如何我可以在不运行代码的情况下跳到下一行吗?再次抱歉,如果这是一个愚蠢的问题。谢谢。 最佳答案 这是一个例子:2.1.2:053>a=1=>12.1.2:054>b=2=>22.1.2:055>a+b=>32.1.2:056>ifa>b#Thecode‘if..."startsthedefinitionoftheconditionalstatement.2.1.2:057?>puts"f

  9. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  10. ruby - 如何在 Rails 4 中使用表单对象之前的验证回调? - 2

    我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser

随机推荐