使用 React 进行 Firebase Google 登录

2025-06-08

使用 React 进行 Firebase Google 登录

介绍

Firebase 身份验证提供了一种使用用户现有社交帐户登录的简便方法。在本教程中,我们将研究如何使用用户的 Google 帐户登录。

我将向你展示

  • 设置 Firebase 项目。
  • 初始化 Firebase 应用。
  • 在 Firebase 中启用用户身份验证。
  • 使用社交服务提供商登录用户
  • 使用 Context API 向子组件提供身份验证状态。
  • 保护路线,即只允许经过身份验证的用户访问路线。
  • 处理用户注销

要求

入门代码

克隆启动代码git clone -b starter https://github.com/gathoni-k/Firebase-Google-Signin.git

首先,前往此处创建项目

点击“开始”按钮, 您将进入项目页面。选择“添加项目”,并为您的项目指定任意名称。您可以选择是否使用 Google Analytics(谷歌分析),并选择 Firebase 帐户,您可以选择默认帐户。 稍后,您将进入项目概览页面。
Firebase 入门

Firebase 添加应用

要添加应用程序,请在“开始...”文本下方单击第三个图标,这将允许您创建一个 Web 应用程序并为您的 Web 应用程序指定一个昵称。

Web 应用昵称

单击下一步并复制 firebaseConfig 对象,我们稍后将使用它来初始化我们的应用程序。

要启用身份验证,请返回项目概览页面并单击“身份验证”选项卡,然后设置登录方法并启用 Google

设置登录方法

好吧,现在开始有趣的事情...... 💃🏾💃🏾

让我们首先抓取之前抓取的 Firebase 配置对象,因为这些是敏感信息,我们需要将其存储在 .env 文件中并将其添加到 .gitignore 文件中,这样我们就不会错误地将其推送到 GitHub 等版本源控制提供商。

话虽如此,在根文件夹中创建一个 .env 文件并添加以下内容

.env



REACT_APP_API_KEY=""
REACT_APP_AUTH_DOMAIN=""
REACT_APP_DATABASE_URL=""
REACT_APP_PROJECT_ID=""
REACT_APP_STORAGE_BUCKET=""
REACT_APP_MESSAGING_SENDER_ID=""
REACT_APP_APP_ID=""
REACT_APP_MEASUREMENT_ID=""


Enter fullscreen mode Exit fullscreen mode

现在使用我们之前获取的 Firebase 配置对象中的相应值来填充它。

注意,REACT_APP_ 前缀是必需的。你可以在这里阅读更多关于在 React 中设置自定义环境变量的信息。

要访问 .env 变量,我们必须安装 dotenv。这是一个 npm 包,可以将 .env 文件中的环境变量加载到 process.env 中。



yarn add dotenv


Enter fullscreen mode Exit fullscreen mode

安装 Firebase



yarn add firebase


Enter fullscreen mode Exit fullscreen mode

现在让我们把所有这些都用起来
创建一个服务文件夹并在其中创建 firebase.js 文件并添加以下代码

src/services/firebase.js



import dotenv from 'dotenv'
dotenv.config()
import * as firebase from "firebase/app";
import "firebase/auth";

firebase.initializeApp({
  apiKey: process.env.REACT_APP_API_KEY,
  authDomain: process.env.REACT_APP_AUTH_DOMAIN,
  databaseURL: process.env.REACT_APP_DATABASE_URL,
  projectId: process.env.REACT_APP_PROJECT_ID,
  storageBucket: process.env.REACT_APP_STORAGE_BUCKET,
  messagingSenderId:  process.env.REACT_APP_MESSAGING_SENDER_ID,
  appId: process.env.REACT_APP_APP_ID,
  measurementId: process.env.REACT_APP_MEASUREMENT_ID
});


Enter fullscreen mode Exit fullscreen mode

在上面的代码中:

  • 我们已经导入了 dotenv 并对其进行了配置。
  • 导入 Firebase
  • 初始化 Firebase 应用 接下来创建一个登录函数,用于使用 Google 账号登录。我们将使用该signInWithPopup()方法。

src/services/firebase.js



export const auth = firebase.auth();
const googleProvider = new firebase.auth.GoogleAuthProvider()
export const signInWithGoogle = () => {
  auth.signInWithPopup(googleProvider).then((res) => {
    console.log(res.user)
  }).catch((error) => {
    console.log(error.message)
  })
}


Enter fullscreen mode Exit fullscreen mode

要使用此功能,我们必须将其导入 Login.js 文件并向登录按钮添加 onClick 处理程序。

src/Login.js



import React from "react";
import "./Login.css"
import { signInWithGoogle } from "./services/firebase";
export default function Login() {
  return (
      <div className="login-buttons">
        <button className="login-provider-button" onClick={signInWithGoogle}>
        <img src="https://img.icons8.com/ios-filled/50/000000/google-logo.png" alt="google icon"/>
        <span> Continue with Google</span>
       </button>
      </div>
  );
}


Enter fullscreen mode Exit fullscreen mode

就这样,您现在可以通过用户的 Google 帐户登录了。
但是,如何防止未经授权的用户访问受保护的路由呢?方法有很多,但我将向您展示如何使用 context API。context API 是一种定义全局变量的方法,这些变量可以通过您的组件访问,而无需将 props 从一个组件传递到另一个组件(即 prop 钻取)。

创建一个 Providers 文件夹并在其中创建一个 UserProvider.js 文件

src/providers/UserProvider.js



import React, {useState, useEffect,  createContext} from "react";
import { auth } from "../services/firebase"
export const UserContext = createContext({user: null})
export default () => {
  const [user, setuser] = useState(null)
  useEffect(() => {
auth.onAuthStateChanged(async (user) => {
  const { displayName, email }  = user;
  setuser({
    displayName,
    email
  })
})
  },[])
  return (
    <UserContext.Provider value={user}>{props.children}</UserContext.Provider>
  )
}


Enter fullscreen mode Exit fullscreen mode

要理解上述代码,首先必须了解 context API。
我们将用户值存储为 context,因此我们使用 createContext() 创建它,并传入用户的初始值(在本例中为 null),然后赋值给变量 UserContext。UserContext
将返回提供值的 Provider 组件。在本例中,它将返回用户。
在默认函数中,我们必须跟踪用户的身份验证状态。这可以通过 onAuthStateChanged 函数完成,该函数由 firebase.auth() 提供,我们在 firebase.js 应用中将其导出为 auth。
用户登录后,状态将更新为其显示名称和电子邮件。
最后,该函数返回包含用户值的 UserContext Provider 组件。

要使用这些值,我们必须将我们想要使用用户值的组件与 UserProvider 组件包装在一起。

src/App.js



import React from "react";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import "./App.css"
import Navbar from "./Navbar"
import Login from "./Login";
import Dashboard from "./Dashboard";
import UserProvider from "./providers/UserProvider";
function App() {
  return (
    <UserProvider>
    <Router>
    <Navbar/>
    <div className="App">
        <Switch>
          <Route exact path="/">
            <Login />
          </Route>
          <Route path="/dashboard">
            <Dashboard />
          </Route>
        </Switch>
    </div>
    </Router>
    </UserProvider>
  );
}

export default App;


Enter fullscreen mode Exit fullscreen mode

用户值现在可以通过 useContext 钩子供我们的组件使用。

src/Login.js



import React, { useContext } from 'react';
import './Login.css'
import { signInWithGoogle } from './services/firebase';
import { UserContext } from './providers/UserProvider';
export default function Login() {
  const user = useContext(UserContext)
  return (
      <div className="login-buttons">
        <button className="login-provider-button" onClick={signInWithGoogle}>
        <img src="https://img.icons8.com/ios-filled/50/000000/google-logo.png" alt="google icon"/>
        <span> Continue with Google</span>
       </button>
      </div>
  );
}


Enter fullscreen mode Exit fullscreen mode

现在怎么办?
现在我们检查用户值,如果通过身份验证,则重定向到仪表板页面

src/Login.js



import React, { useEffect, useContext, useState } from 'react';
import './Login.css'
import { signInWithGoogle } from './services/firebase';
import { UserContext } from './providers/UserProvider';
import { Redirect } from 'react-router-dom';
export default function Login() {
  const user = useContext(UserContext)
  const [redirect, setredirect] = useState(null)

  useEffect(() => {
    if (user) {
      setredirect('/dashboard')
    }
  }, [user])
  if (redirect) {
    <Redirect to={redirect}/>
  }
  return (
      <div className="login-buttons">
        <button className="login-provider-button" onClick={signInWithGoogle}>
        <img src="https://img.icons8.com/ios-filled/50/000000/google-logo.png" alt="google icon"/>
        <span> Continue with Google</span>
       </button>
      </div>
  );
}


Enter fullscreen mode Exit fullscreen mode

这里有一些新东西。首先是重定向状态和 useEffect 钩子。useEffect
钩子将在组件渲染后运行。它会检查用户值,如果存在,则表示用户已通过身份验证,可以重定向到仪表板。
通过将重定向设置为仪表板路径,我们可以正确地重定向用户。太棒了!

但有一个问题,如果用户访问 /dashboard,他们仍然可以访问。我们真的不希望出现这种情况。
为了保护 dashboard 路由,我们必须检查用户的身份验证状态。如果通过身份验证,他们就可以继续访问;如果未通过身份验证,我们会将他们重定向到登录页面,并将其踢出。

src/DashBoard.js



import React from "react";
import "./Dashboard.css";
import React, { useEffect, useContext, useState } from "react";
import { UserContext } from "./providers/UserProvider";
import { Redirect } from "react-router-dom";
export default function Dashboard() {
  const user = useContext(UserContext);
  const [redirect, setredirect] = useState(null);

  useEffect(() => {
    if (!user) {
      setredirect("/");
    }
  }, [user]);
  if (redirect) {
    <Redirect to={redirect} />;
  }
  return (
    <div className="dashboard">
      <h1 className="dashboard-text">Welcome Home</h1>
      <button className="logout-button">
        <img
          src="https://img.icons8.com/ios-filled/50/000000/google-logo.png"
          alt="google icon"
        />
        <span> logout</span>
      </button>
    </div>
  );
}


Enter fullscreen mode Exit fullscreen mode

现在要注销,这很简单。我们只需要调用auth.signOut()我们的firebase.js文件,导入函数,并为注销按钮添加一个onClick处理程序。

src/services/firebase.js



...
export const logOut = () => {
  auth.signOut().then(()=> {
    console.log('logged out')
  }).catch((error) => {
    console.log(error.message)
  })
}


Enter fullscreen mode Exit fullscreen mode

src/Dashboard.js



import React from "react";
import "./Dashboard.css";
import React, { useEffect, useContext, useState } from "react";
import { UserContext } from "./providers/UserProvider";
import { Redirect } from "react-router-dom";
import { logOut } from "./services/firebase";
export default function Dashboard() {
  const user = useContext(UserContext);
  const [redirect, setredirect] = useState(null);

  useEffect(() => {
    if (!user) {
      setredirect("/");
    }
  }, [user]);
  if (redirect) {
    <Redirect to={redirect} />;
  }
  return (
    <div className="dashboard">
      <h1 className="dashboard-text">Welcome Home</h1>
      <button className="logout-button" onClick={logOut}>
        <img
          src="https://img.icons8.com/ios-filled/50/000000/google-logo.png"
          alt="google icon"
        />
        <span> logout</span>
      </button>
    </div>
  );
}


Enter fullscreen mode Exit fullscreen mode

本教程有点长,但就是这样。

感谢阅读🥰

鏂囩珷鏉ユ簮锛�https://dev.to/gathoni/firebase-google-sign-in-with-react-3741
PREV
什么是 DevSecOps?全面了解 DevSecOps
NEXT
Python 来自...Go