Javascript React功能组件中的理想身份验证登录流

Javascript React功能组件中的理想身份验证登录流,javascript,reactjs,authentication,react-router,Javascript,Reactjs,Authentication,React Router,我想知道是否有一种更好的方式来构造我的完整堆栈应用程序中的登录流。现在我的结构如下,包括我正在经历的问题 客户在主页上登录,并呈现组件。应用程序使用useffect()。如果在本地存储中找到用户,请将isAuthenticated状态设置为true,从本地存储中设置user状态,并通过道具呈现组件 若找不到用户,用户将填写组件,后端将表单发送到用户身份验证路由 第一个问题-现在我正在使用一个基于isAuthenticated是否为真的条件渲染。这是最好的方法吗?我见过一些应用程序在经过身份验证后

我想知道是否有一种更好的方式来构造我的完整堆栈应用程序中的登录流。现在我的结构如下,包括我正在经历的问题

  • 客户在主页上登录,并呈现
    组件。应用程序使用
    useffect()。如果在本地存储中找到用户,请将
    isAuthenticated
    状态设置为true,从本地存储中设置
    user
    状态,并通过道具呈现
    组件
  • 若找不到用户,用户将填写
    组件,后端将表单发送到用户身份验证路由
  • 第一个问题-现在我正在使用一个基于
    isAuthenticated
    是否为真的条件渲染。这是最好的方法吗?我见过一些应用程序在经过身份验证后会重定向,也有一些应用程序在经过身份验证后会有条件地呈现
    组件。在我的应用程序中,我两者都在做,我不知道为什么

  • 如果接收到用户对象的后端API,
    setAuthenticated
    为true,将
    user
    状态设置为response,并重定向到“/profile”路由。当客户被重定向到myapp.com/profile时,呈现
    组件。通过道具将
    用户
    状态从
    发送到
  • 同样,我有条件地呈现
    组件并重定向。是这样吗

    代码:

    export const App=()=>{
    const[user,setUser]=useState(null);
    const[authenticated,setAuthenticated]=使用状态(false);
    const[email,setEmail]=useState(“”);
    const[password,setPassword]=useState(“”);
    useffect(()=>{
    _handleLocalStorage();
    }, []);
    const_handleAuthenticated=()=>{
    setTimeout(()=>setAuthenticated(true),1000);
    setReload(false);
    browserHistory.push('/profile');
    };
    const\u handleLocalStorage=async()=>{
    const loggedInUser=await localStorage.getItem('user');
    if(loggedInUser){
    const foundUser=JSON.parse(loggedInUser);
    setUser(foundUser);
    _handleAuthenticated();
    }
    };
    让browserHistory=createBrowserHistory();
    const_handleEmail=(e)=>{
    setEmail(例如target.value);
    };
    常数handlePass=(e)=>{
    设置密码(如目标值);
    };
    常量handleSubmit=async(e)=>{
    e、 预防默认值();
    const token=等待登录(电子邮件、密码);
    const fetchUser=wait getUser(令牌);
    如果(用户){
    setUser(fetchUser);
    setEmail(“”);
    设置密码(“”);
    setItem('user',JSON.stringify(fetchUser));
    _handleAuthenticated();
    }
    };
    const\u handleLogout=async(e)=>{
    const logout=等待axios.get('http://localhost:5000/api/v1/auth/logout');
    console.log(
    `注销状态:${Logout.status},成功:${Logout.data.Success}`
    );
    setAuthenticated(false);
    setReload(false);
    setUser({});
    localStorage.clear();
    browserHistory.push('/');
    };
    返回(
    {!已验证(
    (
    )}
    />
    ) : (
    (
    )}
    />
    )}
    );
    };
    
    一个难题是,当我刷新浏览器上的“/profile”页面时,我会在一瞬间看到登录表单,然后它会加载我的
    组件和数据。当我将我的
    setTimeout()
    函数调整为在10毫秒而不是1000毫秒后启动时,问题得到了有效解决,但这是解决问题的正确方法吗

    但更大的问题是,如果我将浏览器导航回“/”url,它会将我重定向到一个空白的“/配置文件”页面。只有在刷新“/profile”后,才能加载用户数据。为什么会发生这种情况?
    createBrowserHistory()
    是罪魁祸首吗

    所以-我到处都是这个。有谁能在这些问题上给我指出正确的方向吗

    谢谢你的帮助

    export const App = () => {
        const [user, setUser] = useState(null);
        const [authenticated, setAuthenticated] = useState(false);
        const [email, setEmail] = useState('');
        const [password, setPassword] = useState('');
    
        useEffect(() => {
            _handleLocalStorage();
        }, []);
    
        const _handleAuthenticated = () => {
            setTimeout(() => setAuthenticated(true), 1000);
            setReload(false);
            browserHistory.push('/profile');
        };
    
        const _handleLocalStorage = async () => {
            const loggedInUser = await localStorage.getItem('user');
            if (loggedInUser) {
                const foundUser = JSON.parse(loggedInUser);
                setUser(foundUser);
                _handleAuthenticated();
            }
        };
    
        let browserHistory = createBrowserHistory();
    
        const _handleEmail = (e) => {
            setEmail(e.target.value);
        };
    
        const _handlePass = (e) => {
            setPassword(e.target.value);
        };
    
        const _handleSubmit = async (e) => {
            e.preventDefault();
            const token = await login(email, password);
            const fetchUser = await getUser(token);
            if (fetchUser) {
                setUser(fetchUser);
                setEmail('');
                setPassword('');
    
                localStorage.setItem('user', JSON.stringify(fetchUser));
                _handleAuthenticated();
            }
        };
    
        const _handleLogout = async (e) => {
            const logout = await axios.get('http://localhost:5000/api/v1/auth/logout');
            console.log(
                `Logout status: ${logout.status}, Success: ${logout.data.success}`
            );
            setAuthenticated(false);
            setReload(false);
            setUser({});
            localStorage.clear();
            browserHistory.push('/');
        };
    
        
    
        return (
            <Router>
                <div>
                    {!authenticated ? (
                        <Route
                            path='/'
                            render={(props) => (
                                <Login
                                    {...props}
                                    handleEmail={_handleEmail}
                                    handlePass={_handlePass}
                                    handleSubmit={_handleSubmit}
                                />
                            )}
                        />
                    ) : (
                        <Route
                            exact
                            path='/profile'
                            render={(props) => (
                                <loggedIn {...props} user={user} logout={_handleLogout} />
                            )}
                        />
                    )}
                </div>
            </Router>
        );
    };