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

2023-11-27

Question

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

Goal

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

限制

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

研究成果

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

Setup

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

反应本机设置

当前文件夹结构:

> 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数据库您可以使用其服务器端安全规则以确定每个用户有权访问的内容。在这里你可以限制来自特定域的用户的访问.

另请参阅:

  • 将 Firebase Google OAuth 身份验证限制为特定用户
  • 如何在 Firebase 3.x 中禁用注册
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 React Native 中限制 google 登录到我公司的电子邮件域 (@company.com)? 的相关文章

  • 如何获取每个StorageVolume的可用大小和总大小?

    背景 谷歌 悲伤 计划破坏存储权限 https www xda developers com android q storage access framework scoped storage 这样应用程序将无法使用标准文件 API 和文件
  • 如何在 Linux 内核中定义并触发我自己的新软中断?

    我想在 Linux 内核中创建自己的软中断 这是正确的方法吗 In the init我想触发该模块的softirq我将添加一个调用 394 void open softirq int nr void action struct softir
  • 将现有 VARCHAR 列与 Room 结合使用

    我正在尝试将现有的数据库与 Android Room 一起使用 但是 我的一个表有一个 VARCHAR 列 Room 似乎只支持 TEXT 不支持 VARCHAR 而且 sqlite 不允许修改列类型 那么 有没有办法使用Room中现有的带
  • Android 初学者:Android gridview 中的触摸事件

    我正在使用以下代码来使用 gridview 执行操作 稍作修改http developer android com resources tutorials views hello gridview html http developer a
  • 如何更改终端的默认目录?

    我想更改 Android Studio v2 2 2 终端的默认目录 当我打开终端时 它基于项目的目录 C 项目路径 我经常需要使用adb shell 所以我必须导航到 SDK 路径 平台工具 才能使用 adb 命令 是否可以更改终端的默认
  • 在 android 中建立与 MySQL 的池连接

    我需要从我的 Android 应用程序访问 MySQL 数据库 现在所有的工作都通过 DriverManager getConnection url 等等 但我必须从多个线程访问数据库 所以我必须使用连接池 问题1 是 com mysql
  • Android:后台Activity可以执行代码吗?

    后台的活动是否被视为 正在运行 并且可以执行代码 还是处于挂起状态 他们暂停了 活动生命周期 http developer android com reference android app Activity html ActivityLi
  • 为什么是 javascript:history.go(-1);无法在移动设备上工作?

    首先 一些背景 我有一个向用户呈现搜索页面 html 表单 的应用程序 填写标准并单击 搜索 按钮后 结果将显示在标准部分下方 在结果列表中 您可以通过单击将您带到新页面的链接来查看单个结果的详细信息 在详细信息页面中 我添加了一个 返回结
  • 当 OnFocusChangeListener 应用于包装的 EditText 时,TextInputLayout 没有动画

    不能比标题说得更清楚了 我有一个由文本输入布局包裹的 EditText 我试图在 EditText 失去焦点时触发一个事件 但是 一旦应用了事件侦听器 TextInputLayout 就不再对文本进行动画处理 它只是位于 editText
  • 使用 luasocket smtp 和 ssl 发送电子邮件

    我一直在尝试使用帖子中描述的代码发送电子邮件 lua使用gmail账户发送邮件 https stackoverflow com questions 11070623 lua send mail with gmail account 代码由米
  • 对于一个单元格,RecyclerView onBindViewHolder 调用次数过多

    我正在将 RecyclerView 与 GridLayoutManager 一起使用 对于网格中的每个项目 我需要调用 REST api 来检索数据 然后 从远程异步获取数据后 我使用 UIL 加载 显示图像 一切似乎都很好 但我发现 on
  • logcat 中 mSecurityInputMethodService 为 null

    我写了一点android应显示智能手机当前位置 最后已知位置 的应用程序 尽管我复制了示例代码 并尝试了其他几种解决方案 但似乎每次都有相同的错误 我的应用程序由一个按钮组成 按下按钮应该log经度和纬度 但仅对数 mSecurityInp
  • Mipmap 与可绘制文件夹[重复]

    这个问题在这里已经有答案了 我正在使用 Android Studio 1 1 Preview 1 我注意到 当我创建一个新项目时 我得到以下层次结构 不同 DPI 的 Mipmap 文件夹 不再有不同 DPI 的可绘制文件夹 我应该将所有资
  • Android 2.3 模拟器在更新位置时崩溃

    我正在使用 Eclipse 编写和调试 Android 应用程序 我需要做的事情之一是更新设备的位置 因此我尝试使用模拟器控制窗口中的位置控制面板 在 手动 选项卡上 我选择 十进制 输入有效的纬度和经度 然后单击 发送 不幸的是 接下来发
  • Android Studio 缓慢的增量构建

    我已经完成了许多步骤来完善我们的构建系统 those https stackoverflow com questions 16775197 building and running app via gradle and android st
  • Android - 以编程方式选择菜单选项

    有没有办法以编程方式选择菜单选项 基本上 我希望视图中的按钮能够执行与按特定菜单选项相同的操作 我正在考虑尝试调用 onOptionsItemSelected MenuItem item 但我不知道要为菜单项添加什么 是的 有一种方法可以选
  • 插件“Android Bundle Support”不兼容

    大家好 自从上次更新以来 当我启动 android studio 时 我遇到了一个非常奇怪的错误 我有这个错误 插件错误 插件 Android Bundle Support 不兼容 直到构建 AI 195 SNAPSHOT 我在网上找不到任
  • 在 Android 应用程序资源中使用 JSON 文件

    假设我的应用程序的原始资源文件夹中有一个包含 JSON 内容的文件 我如何将其读入应用程序 以便我可以解析 JSON See 开放原始资源 http developer android com reference android conte
  • CamcorderProfile.videoCodec 返回错误值

    根据docs https developer android com reference android media CamcorderProfile html 您可以使用CamcorderProfile获取设备默认视频编解码格式 然后将其
  • Android 后台倒计时器

    我有一个 Android 应用程序 它管理一个倒计时器 类 CountDownTimer 它显示在应用程序屏幕中 以显示到达 00 00 还剩多少时间 我现在的问题是 当我按主页按钮或启动另一个应用程序时 应用程序 计时器不会在后台运行 所

随机推荐

  • 错误“超出最大更新深度。当组件在 useEffect 中调用 setState 时可能会发生这种情况”

    每当调用我的购物车组件 也如下所示 时 我都会遇到此错误 重复数千次 直到页面崩溃 index js 1 Warning Maximum update depth exceeded This can happen when a compon
  • 如何根据依赖关系进行排序?

    我有一个类 其中包含指向相同基类型的其他类的 依赖项 列表 class Foo Base dependencies class Bar Base dependencies Foo class Baz Base dependencies Ba
  • PyInstaller 文件无法执行脚本 - DistributionNotFound

    我正在尝试使用 PyInstaller 将 python 文件转换为可执行文件 该程序使用谷歌云翻译 API在语言之间翻译给定文本 跑步时python quicktrans py在终端中 程序运行良好 然后我跑了pyinstaller qu
  • Xcode - 未连接配置的 iOS 设备

    今天下午我正在使用 Xcode 并在我的设备上调试应用程序 效果很好 当我从办公室回到家并插入手机继续工作时 XCode 将不再让我在设备上进行调试 我收到的错误是 Error Starting Executable No provisio
  • Pandas 最大值指数

    我有一个混合了屏幕名称 推文 收藏夹等的 Pandas DataFrame 我想找到 favcount 的最大值 我已经完成了 并返回该 推文 的屏幕名称 df pd DataFrame df timestamp timestamp df
  • SSRS如何添加新行

    我正在从这样的存储过程创建一个字符串Name1 Name2 Name 3 等等 该字符串位于一列中 我想在 SSRS 报告中的新行中显示这些名称 例如 Name1 Name2 Name3 我尝试将字符串更改为 Name1 VbCrlf Na
  • 从 http 基本身份验证中排除特定的 cakephp 控制器

    我试图排除路径 URI 被基本 http 身份验证阻止 路径是 rest http example com rest 并代表 cakephp 3 应用程序的控制器 它不是一个真实的文件 而是一个由重写条件重写并由 webroot 目录中的
  • r sf包多边形内的质心

    我需要向多边形添加标签 并且通常使用质心 但是质心不会落在多边形内 我发现这个问题计算 SpatialPolygon 内 内部的质心但我正在使用 sf 包 下面是玩具数据 rm list ls all TRUE start with emp
  • 绘制矩形和Interface Builder之间的颜色差异?

    简而言之 我在界面生成器中有 2 个视图 其中一个使用界面生成器中的 RGB 滑块设置为颜色 99 99 99 另一个视图以编程方式着色以实现某种形状 我使用以下方式填充它 Obviously this is in drawRect UIC
  • 如何修改非常大的 zip 中的单个文件而不重写整个 zip?

    我有包含巨大文件的大型 zip 文件 zip 存档中有一些需要修改的 元数据 文本文件 但是 无法提取整个 zip 并重新压缩它 我需要在 zip 中找到目标文本文件 对其进行编辑 并可能将更改附加到 zip 文件中 文本文件的文件名始终相
  • 从 Option>> 解开并访问 T

    我正在尝试用 Rust 解决一些 Leetcode 问题 然而 我在使用 LeetCode 时遇到了一些困难TreeNode执行 use std cell RefCell use std rc Rc TreeNode data struct
  • Android:WebView的方法goBack()显示空白页面

    我有一个 Android 应用程序 它使用 WebView 在活动中加载网页 我正在使用手动检索页面并使用 WebView 的使用BaseURL加载数据将其显示在屏幕上 那里的一切都很好 现在 我尝试覆盖 后退 按钮按下以模拟在 WebVi
  • 如何将 iOS React Native 模板转换为 Swift?

    我一直在阅读有关 React Native 的内容 并决定尝试一下 我在 Swift 方面很有经验 但从未尝试过 Objective C 所以我想将模板项目转换为使用 AppDelegate swift 我按照这个接受的答案中的解决方案进行
  • Fetch API 与 XMLHttpRequest

    我知道 Fetch API 使用Promises 并且它们都允许您向服务器发出 AJAX 请求 我读到 Fetch API 有一些额外的功能 这些功能在XMLHttpRequest 以及在 Fetch API polyfill 中 因为它基
  • 什么时候有人会使用工会?这是纯 C 时代的残余吗?

    我学到了 但并没有真正加入工会 我读过的每本 C 或 C 文本都会介绍它们 有时是顺便介绍 但它们往往很少给出关于为什么或在哪里使用它们的实际示例 工会何时在现代 甚至遗留 情况下有用 我唯一的两个猜测是 当您的工作空间非常有限时 或者当您
  • 如何将compile_commands.json与clang python绑定一起使用?

    我有以下脚本尝试打印给定 C 文件中的所有 AST 节点 当在具有简单包含的简单文件 同一目录中的头文件等 上使用它时 效果很好 usr bin env python from argparse import ArgumentParser
  • 如何在生产中禁用转储 symfony 功能

    如何禁用dump 功能 什么时候在生产环境中 如果我忘记了转储功能 它会崩溃并出现 500 错误 你应该删除dump 来自您的生产代码 它不必在那里 But as noted by Cerad 因为当您在签入之前忘记删除它们时可能会很烦人
  • 我如何告诉 PyCharm 参数的预期类型是什么?

    当涉及到构造函数 赋值和方法调用时 PyCharm IDE 非常擅长分析我的源代码并找出每个变量应该是什么类型 我喜欢它正确的时候 因为它为我提供了良好的代码完成和参数信息 并且如果我尝试访问不存在的属性 它会给我警告 但当涉及到参数时 它
  • 映射缩减组合器

    我有一个带有映射器 减速器和组合器的简单映射缩减代码 映射器的输出被传递到组合器 但是对于reducer来说 传递的不是combiner的输出 而是mapper的输出 请帮忙 Code package Combiner import jav
  • 如何在 React Native 中限制 google 登录到我公司的电子邮件域 (@company.com)?

    Question 阻止用户使用不以 mycompany com 结尾的电子邮件地址通过 Firebase Google 身份验证登录我们的内部应用程序的最佳方法是什么 Goal 防止用户使用错误的电子邮件登录应用程序 获取用户的公司电子邮件