首页 > 解决方案 > 在不阻塞路由的情况下保护页面

问题描述

以下问题:我正在尝试在反应中创建一个身份验证系统,让用户登录、注册和重置密码。问题是,我想让用户走某些路线,比如/profile,但是如果他登录了就显示内容。如果他没有登录,我想简单地显示导航栏和一个小的登录组件。

到目前为止,我尝试过这样的事情:(为了使其更具可读性,我省略了动作块)

const Profile = ({ history }) => {
  const [values, setValues] = useState({
    username: "",
    email: "",
    password: ""
  });

  const [isShowingAuth, setIsShowingAuth] = useState(null);

  const { username, email, password } = values;


  useEffect(() => {

    if (!isLoggedIn()) {
      setIsShowingAuth("login");
    } else {
      loadProfileData();
    }
  }, []);

  const loadProfileData = () => {
    const userEmail = isLoggedIn().email;
    const token = getCookie("token");

    axios({
      method: "GET",
      url: `${process.env.REACT_APP_BACKEND_URL}/user`,
      headers: { Authorization: `Bearer ${token}` },
      data: { userEmail }
    })
      .then(response => {
        // Do something
      })
      .catch(error => {
        // Do something
      });
  };

  const handleChange = name => event => {
    setValues({ ...values, [name]: event.target.value });
  };

  const handleUpdateUserSubmit = e => {
    e.preventDefault();

    const token = getCookie("token");

    axios({
      method: "PUT",
      url: `${process.env.REACT_APP_BACKEND_URL}/user/update`,
      headers: { Authorization: `Bearer ${token}` },
      data: { username, password, email }
    })
      .then(response => {
        // Do something 
      })
      .catch(error => {
        // Do something
        }

        store.addNotification({
          ...defaultSettings,
          type: "danger",
          title: "User update error",
          message: error.response.data.errorMsg
        });
      });
  };


  const deleteAccount = () => {
    const token = getCookie("token");

    axios({
      method: "DELETE",
      url: `${process.env.REACT_APP_BACKEND_URL}/user`,
      headers: { Authorization: `Bearer ${token}` }
    })
      .then(response => {
        // Do something
      })
      .catch(error => {
        // Do something
  };

  const showDeleteConfirmation = () => {
      // Do something
  };

  return (
    <Layout isShowingAuth={isShowingAuth}>
      {isLoggedIn() && isLoggedIn().role === "member" ? (
        <>
          <ReactNotifications />
          <h1 className='mt-5 pl-3'>Profile</h1>
          <form className='form col-md-6 mt-3'>
            <div className='form-group'>
              <label>Name</label>
              <input
                type='text'
                className='form-control'
                value={username}
                onChange={handleChange("username")}
              />
            </div>
            <div className='form-group'>
              <label>Email</label>
              <input
                type='email'
                className='form-control'
                value={email}
                onChange={handleChange("email")}
                disabled
              />
            </div>
            <div className='form-group'>
              <label>Password</label>
              <input
                type='password'
                className='form-control'
                value={password}
                onChange={handleChange("password")}
                placeholder='Enter your new password'
                autoComplete='on'
              />
            </div>
            <button type='submit' className='btn btn-outline-primary' onClick={handleUpdateUserSubmit}>
              Update User
            </button>
            <button type='button' className='btn btn-outline-danger ml-3' onClick={showDeleteConfirmation}>
              Delete account
            </button>
            <button type='button' className='btn btn-outline-danger ml-3 mt-2 mt-md-0'>
              Want to change your email?
            </button>
          </form>
          {showAlert}
        </>
      ) : null}
    </Layout>
  );
};

基本上,如果用户登录,我正在检查该isLoggedIn()方法。如果是,我想渲染内容,如果不是,我只返回布局。布局包含导航栏。

现在的问题是,一旦用户在路由 /profile 上登录,该组件就不会重新安装,这意味着useEffect(()=> {},[])不会再次调用该组件,并且我的配置文件数据也不会加载。

通过 登录后,我已经尝试刷新页面history.push(history.location.pathname),但这也不会触发重新挂载。

我不知道如何在登录后正确触发重新安装,以及我设置身份验证系统的方式是否安全,或者是否有更好的解决方案。

任何帮助/反馈感谢感谢:)

标签: javascriptreactjsauthenticationreact-routeruse-effect

解决方案


推荐阅读