gpt4 book ai didi

javascript - 使用 if 语句确定 Firebase 用户是否可以访问某些 React Router 路径

转载 作者:行者123 更新时间:2023-12-03 07:23:45 25 4
gpt4 key购买 nike

我有一个 React Web 应用程序,其路由是通过 React Router 定义的。

应用上的身份验证是通过 Firebase 完成的,我希望根据用户是否登录来保护某些路由。

为了确定用户是否登录,我使用了以下函数:

let user = firebase.auth().currentUser;

if (user) {

} else {

}
}

从那里,我认为我可以将“ protected ”路由放入初始 if 中,因为这将确定用户是否已登录,如下所示:

    let user = firebase.auth().currentUser;

if (user) {
<div>
<Route path="/dashboard" component={Dashboard} exact />
</div>

} else {
<Route path="/sign-in" component={SignIn} />
}
}

如果用户未登录,那么他们将被重定向到登录组件。

但这不起作用。仪表板页面只是以空白屏幕的形式返回,而不是重定向。

确实,控制台中显示了一条错误消息:

Warning: Failed prop type: Invalid prop children supplied to Switch, expected a ReactNode.

作为引用,这是我的完整组件:

class App extends Component {
constructor(props) {
super(props)

this.userLoggedIn = this.userLoggedIn.bind(this)

}


userLoggedIn = () => {
let user = firebase.auth().currentUser;

if (user) {
<div>
<Route path="/dashboard" component={Dashboard} exact />
</div>
} else {
<Route path="/sign-in" component={SignIn} />
}
}

render() {
return (
<div>

<Switch>

{this.userLoggedIn}

<Route exact path="/" component={Homepage} />
<Route path="/sign-in" component={SignIn} />
<Route path="/register" component={Register} />

</Switch>

</div>
)
}
}

我知道逻辑有缺陷,但有没有办法重构我的代码来实现这个非常简单的黑客攻击,以使用 Firebase Auth 获取 protected 路由?

希望这很清楚,如果需要更多信息,请告诉我。

编辑:根据答案编辑了我的代码,但现在收到以下错误消息:

TypeError: Right side of assignment cannot be destructured
PrivateRoute
src/PrivateRoute.js:8
5 | import { AuthContext } from './Auth'
6 |
7 | export default function PrivateRoute({ component: RouteComponent, ...rest }) {
> 8 | const {currentUser} = useContext(AuthContext)
9 | return (
10 | <Route
11 | {...rest}

我更新的代码...

Auth.js

import React, { useEffect, useState } from 'react'
import * as firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";
import firebaseConfig from './firebaseConfig';


export const AuthContext = React.createContext();

export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState(null);

useEffect(() => {
firebase.auth().onAuthStateChanged(setCurrentUser);
}, []);

return (
<AuthContext.Provider
value={{currentUser}}
>
{children}
</AuthContext.Provider>
)
}

PrivateRoute.js

import React, { useContext } from 'react';
import { Route, Redirect } from 'react-router-dom';
import { AuthContext } from './Auth'

export default function PrivateRoute({ component: RouteComponent, ...rest }) {
const { currentUser } = useContext(AuthContext)
return (
<Route
{...rest}
render={routeProps =>
!!currentUser ? (
<RouteComponent {...routeProps} currentUser={currentUser} />
) : (
<Redirect to={'/signin'}/>
)
}
/>
)
}

App.js

import React, { Component } from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import PrivateRoute from './PrivateRoute';
import './App.css';
import * as firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";
import firebaseConfig from './firebaseConfig';


class App extends Component {

render() {
return (
<div>

<Switch>

<PrivateRoute path="/dashboard" component={Dashboard} />
<Route exact path="/" component={Homepage} />
<Route path="/sign-in" component={SignIn} />
<Route path="/register" component={Register} />

</Switch>

</div>
)
}
}

export default App;

最佳答案

有两种方法可以解决这个问题并稍微清理一下。

假设您只希望经过身份验证的用户访问仪表板页面

简单的选择:

class App extends Component {

state = {
currentUser: undefined
}

componentDidMount(){
const user = firebase.auth().currentUser
this.setState({currentUser: user})
}

render() {
return (
<div>

<Switch>

<Route exact path="/dashboard">
{this.state.user ? (
<Dashboard />
) : (
<Redirect to={"/login"} />
)}
</Route>

</Switch>

</div>
)
}
}

一些注意事项:

  • 最好使用 componentDidMount() 获取当前用户并在组件安装时设置任何初始状态。 .
  • React 支持像我一样简单地声明初始状态,而不是使用构造函数
  • 最后,react-router 有一个 <Redirect to={path}/>组件,这对于检查经过身份验证的用户等用例非常有用。

清洁工(也是我的首选):

如果您想抽象身份验证过程并让您的生活更简单,从长远来看,您可以创建 2 个文件(例如 base.jsAuth.jsPrivateRoute.js )

  • base.js是我们要初始化 firebase 的地方

    import * as firebase from 'firebase/app'

    const app = firebase.initializeApp({
    apiKey: process.env.REACT_APP_FIREBASE_KEY,
    authDomain: process.env.REACT_APP_FIREBASE_DOMAIN,
    databaseURL: process.env.REACT_APP_FIREBASE_DATABASE,
    projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
    storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
    messagingSenderId: process.env.REACT_APP_FIREBASE_SENDER_ID,
    measurementId: process.env.REACT_APP_MEASUREMENT_ID
    });

    export default app;

注释:

  • 我已经输入了process.env......作为 API key 的值,因为将 key 保存在 .env 中始终是最佳实践文件。

  • Auth.js是当经过身份验证的状态发生变化时我们将处理获取经过身份验证的用户的地方

Auth.js:

import React, { useEffect, useState } from 'react'
import app from './base'

export const AuthContext = React.createContext();

export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState(null);

useEffect(() => {
app.auth().onAuthStateChanged(setCurrentUser);
}, []);

return (
<AuthContext.Provider
value={{currentUser}}
>
{children}
</AuthContext.Provider>
)
}

注释:

  • 不要忘记导入 React、useState、useEffect 和 firebase
  • 此文件将提供身份验证上下文,以便您可以从 React 应用程序中的任何位置获取它

PrivateRoute.js:

import React, { useContext } from 'react';
import { Route, Redirect } from 'react-router-dom';
import { AuthContext } from './Auth'

export default function PrivateRoute({ component: RouteComponent, ...rest }) {
const currentUser = useContext(AuthContext)
return (
<Route
{...rest}
render={routeProps =>
!!currentUser ? (
<RouteComponent {...routeProps} currentUser={currentUser} />
) : (
<Redirect to={'/login'}/>
)
}
/>
)
}

注释:

  • 在这里,我们从 Auth.js 导入身份验证上下文文件并获取当前用户。
  • 然后我们将创建一个 PrivateRoute ,它检查是否存在当前用户,如果存在,则使用 RouteRedirect来自react-router-dom包我们可以将用户重定向到 /login页面(如果未经过身份验证)或访问 RouteComponent它与附加 Prop (如果有的话)一起传递。
  • 我们还传递 currentUserRouteComponent作为 props,因此它可以在该组件中使用。

有了这个,您现在可以使用 PrivateRoute像这样的组件以确保只有经过身份验证的用户才能使用给定的组件:

import PrivateRoute from "./PrivateRoute";
import Dashboard from "./Dashboard"

<PrivateRoute exact path="/dashboard" component={Dashboard} />

关于javascript - 使用 if 语句确定 Firebase 用户是否可以访问某些 React Router 路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64577966/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com