【问题标题】:Protected Routes in React-Ionic app using Firebase Auth Context使用 Firebase Auth Context 的 React-Ionic 应用程序中的受保护路由
【发布时间】:2021-01-17 23:31:38
【问题描述】:

我正在尝试在 React-Ionic 应用程序中为 Firebase 身份验证设置上下文,其中包含一些未经身份验证的情况下不应访问的受保护路由。到目前为止,它有点工作,但不完全。我可以毫无问题地登录并使用受保护的路线导航页面,但是一旦我刷新页面,它就会带我回到登录页面,就好像我没有经过身份验证一样。

我很确定我在某处搞砸了,但无法检测到哪里(实际上可能整个事情都被错误地实现了,因为我对此很陌生并且仍在学习)。

这是我的文件到目前为止的样子(没有导入和其他东西,只是核心部分):

App.tsx

const App: React.FC = () => {

  const authContext = useContext(AuthContext);

  useEffect(() => {
    console.log(authContext) **//**
  }, [])  

  return (
    <IonApp>
      <IonReactRouter>
        <IonRouterOutlet>
          <Route exact path="/" component={PageLogin} />
          <ProtectedRoute path="/secure/home" component={PageHome} isAuthenticated={authContext.authenticated!}/>
          <ProtectedRoute path="/secure/lot/:lotId" component={PageLotOverview} isAuthenticated={authContext.authenticated!}/>
          <ProtectedRoute path="/secure/shipment/:shipmentId" component={PageShipmentOverview} isAuthenticated={authContext.authenticated!}/>
        </IonRouterOutlet>
      </IonReactRouter>
    </IonApp>
  )
}

AuthProvider.tsx:

export const AuthContext = React.createContext<Partial<ContextProps>>({});

export const AuthProvider = ({ children }: any) => {

  const [user, setUser] = useState(null as firebase.User | null);
  const [loadingAuthState, setLoadingAuthState] = useState(true);

  useEffect(() => {
    firebase.auth().onAuthStateChanged((user: any) => {
      setUser(user);
      setLoadingAuthState(false);
    });
  }, []);

  return (
    <AuthContext.Provider
      value={{
        user,
        authenticated: user !== null,
        setUser,
        loadingAuthState
      }}>
      {children}
    </AuthContext.Provider>
  );
}

ProtectedRoute.tsx:

interface ProtectedRouteProps extends RouteProps {
  component: React.ComponentType<any>;
  path: string;
  isAuthenticated: boolean
}


export const ProtectedRoute: React.FC<ProtectedRouteProps> = ({ component: Component, path, isAuthenticated }) => {

  useEffect(() => {
    console.log("from protected ROUTE", isAuthenticated)
  }, [])

return (
    <Route path={path} render={() => isAuthenticated ? <Component /> : <Redirect to="/" />} />
  );
};

index.tsx:

ReactDOM.render(
  <AuthProvider>
    <App />
  </AuthProvider>
  , document.getElementById('root'));

如果我能提供更多有用的信息,请告诉我。提前感谢您的帮助。

【问题讨论】:

    标签: reactjs typescript firebase ionic-framework


    【解决方案1】:

    第一:每个人都还在学习

    第二个:我个人使用了一个非常简单的解决方案(工作正常)。您可以使用称为“会话存储”的工具。

    从 Firebase 获取用户数据后,请立即执行以下操作:

    
    // When login is successful
    
    sessionStorage.setItem('isLogged', 'true'); 
    
    // This will create a variable with value *true* that 
    can be accessed from any page within your website
    
    

    会话存储就像一个本地数据库,可以存储您想要保存的任意数量的值,并且不会在刷新时被删除。但是它只是暂时的,当用户关闭浏览器窗口时会被删除。

    现在,您可以在每条受保护的路线上执行此操作。

    useEffect(() => {
      if(sessionStorage.getItem('isLogged') == 'false')
      {
        window.location.href = '/login' // send the user to login page
      }
    }, [])
    

    专业提示

    使用可以使用此机制为您正在开发的任何内容实现“记住我”选项。在这种情况下,您可能必须使用类似于sessionStorageLocalStorage,但即使用户关闭浏览器窗口,它也不会删除数据。

    当用户访问您的页面时,它会自动将用户重定向到主页而无需登录(如果您创建 useEffect 来检查)。

    另一件事:localStoragesessionStorage 对于不同的用户是不同的。存储在我浏览器的localStoragesessionStorage 中的值将不会对您或除我之外的任何人可见。

    就是这样

    【讨论】:

    • 非常感谢您的快速回答,非常感谢。如果我理解正确,用你的方法就没有必要再有“ProtectedRoute”组件了,对吧?我只需要使用普通的 Route 组件并在需要身份验证的每个页面上放置一个 useEffect 检查 sessionStorage 就可以了。好吧,在那种情况下,我什至不明白为什么拥有 AuthContext 将不再有用。在这种情况下,我会感到有些困惑。您的解决方案看起来很简单,为什么还要费心设置 AuthContext?
    猜你喜欢
    • 2018-08-11
    • 1970-01-01
    • 2021-04-06
    • 2020-04-26
    • 1970-01-01
    • 2020-08-18
    • 2020-10-26
    • 2019-05-31
    • 2021-03-17
    相关资源
    最近更新 更多