【问题标题】:How to create a Protected Route with Promises如何使用 Promise 创建受保护的路由
【发布时间】:2020-07-09 04:47:55
【问题描述】:

我正在使用挂钩来保护我的路线。我遇到的问题是检查用户身份验证状态的调用返回一个 Promise,因此该钩子返回默认值,即 a,然后身份验证状态不再有用,因为我们已经重定向了。

那么我怎么能等到身份验证检查完成才从钩子返回呢?这是我的代码:

export function ProtectedRoute(props){

const [loggedIn, setLoggedIn] = useState(false);

// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
    async function fetchUser() {
        let user = null;

        try {
            user = await Auth.currentAuthenticatedUser()
            if (user) {
                setLoggedIn(true);
            } else
            {
                setLoggedIn(false);
            }
        } catch (e) {
            setLoggedIn(false);
        }
    }
    fetchUser()
});

console.log("ProtectedRoute: returning " + loggedIn);
if (loggedIn)
    return props.component
else
    return <Redirect to={{pathname: '/login'}}/>

}

【问题讨论】:

    标签: reactjs react-router amazon-cognito react-router-dom aws-amplify


    【解决方案1】:

    找到一个解决方案...必须默认为 isAuthenticated 为“true”,如果不是这种情况,则重定向(重定向似乎在我的初始代码中破坏了我的逻辑)

    export function ProtectedRoute({ component: Component, ...rest }){
    
    const [isAuthenticated, setLoggedIn] = useState(true);
    useEffect(() => {
        (async () => {
            let user = null;
    
            try {
                user = await Auth.currentAuthenticatedUser()
                if (user) {
                    setLoggedIn(true);
                } else
                {
                    setLoggedIn(false);
                }
            } catch (e) {
                setLoggedIn(false);
            }
        })();
    });
    
    return (
        <Route
            {...rest}
            render={props =>
                isAuthenticated ? <Component {...props} /> : <Redirect to="/login" />
            }
        />
    );
    

    }

    【讨论】:

    • 如果1分钟没有服务器响应会发生什么? (或者用户手动减慢应用程序的速度?) - 路由没有得到保护 -
    • 我不太关心这一点,因为除非用户登录(没有有效的 JWT 令牌),否则用户将无法在该路由中执行任何操作。
    • 顺便说一句,这种“保护”主要是装饰性的。真正的保护是在后端完成的。另一方面,如果您的服务器响应需要很长时间,则需要重新构建应用程序。失败需要快速发生。
    【解决方案2】:

    我会添加一个新状态loading,直到出现true,只渲染一个加载组件:

        export default ProtectedRoute(props) {
        
          const [loggedIn, setLoggedIn] = useState(false);
          const [loading, setLoading] = useState(true);
          
          useEffect(() => {
            (async () => {
              try {
                setLoading(true);
                const user = await Auth.currentAuthenticatedUser();
                setLoggedIn(!!user);
              } catch (error) {
                console.log(error);
                setLoggedIn(false);
              } finally {
                setLoading(false);
              }
            })();
          }, []);
        
          if(loading) return <h1>Loading...</h1>;
            
          if (loggedIn) return props.component
        
          return <Redirect to={{ pathname: '/login' }}/>
      }
    

    【讨论】:

    • 它立即重定向,因为对 Cognito 的调用需要一些时间,然后组件永远不会加载。
    猜你喜欢
    • 2021-05-23
    • 1970-01-01
    • 2020-08-18
    • 2021-04-06
    相关资源
    最近更新 更多