使用Firebase身份验证上下文的React-Ionic应用程序中的受保护路由

时间:2020-10-02 09:12:02

标签: reactjs typescript firebase ionic-framework

我正在尝试使用一些受保护的路由在React-Ionic应用程序中设置Firebase身份验证的上下文,这些路由必须经过身份验证才能访问。到目前为止,它还可以,但是还不完全。我可以毫无问题地登录并使用受保护的路线导航页面,但是刷新页面后,它会立即回到登录页面,就像我没有经过身份验证一样。

我很确定我将事情弄乱了,但是却无法检测到什么地方(实际上很可能整个事情都被错误地实现了,因为我对此还很陌生并且还在学习)。 / p>

这是到目前为止我的文件的外观(没有导入和填充,只是核心部分):

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

受保护的Route.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'));

请告知我是否可以提供更多有用的信息。预先感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

数字1:每个人都还在学习

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

从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
  }
}, [])

专业提示

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

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

另一件事:localStoragesessionStorage对于不同的用户而言是不同的。除了我以外,您或任何人都无法看到存储在浏览器localStoragesessionStorage中的值。

就这样