【问题标题】:Using react-private-route when token is in local storage当令牌在本地存储中时使用 react-private-route
【发布时间】:2020-06-09 07:57:50
【问题描述】:

如果身份验证成功,我正在尝试使用 react-private-route 创建私有路由以将用户引导到授权的 /panel 页面:

https://github.com/hansfpc/react-private-route

对于身份验证,提交按钮向 graphql 后端发送一个变异请求。如果身份验证成功,则后端会发回一个令牌,该令牌存储在 localStorage 中。 这是我的登录页面代码的样子:我需要在这里修改吗?

const LoginMutation = gql`
mutation LoginMutation($email: String!, $password: String!) {
  loginEmail(email: $email, password: $password)
}
`;

const schema = Yup.object({
  email: Yup
    .string()
    .email('Invalid Email')
    .required('Please Enter your Email'),
  password: Yup
    .string()
    .required('Please Enter your password')
});

function LoginPage (){
  const [state, setState] = useState({
    email: '',
    password: '',
    loggedIn: false,
  });  


  function submitForm(LoginMutation: any) {
    const { email, password } = state;
    console.log(email, password)
    if(email && password){
      LoginMutation({
        variables: {
            email: email,
            password: password,
        },
    }).then(({ data }: any) => {
      localStorage.setItem('token', data.loginEmail);
    })
    .catch(console.log)

    }
  }

    return (
      <Mutation mutation={LoginMutation}>
        {(LoginMutation: any) => (
              <Typography component="h1" variant="h5">
                Sign in
              </Typography>
              <Formik
                initialValues={{ email: '', password: '' }}
                onSubmit={(values, actions) => {
                  setTimeout(() => {
                    alert(JSON.stringify(values, null, 2));
                    actions.setSubmitting(false);
                  }, 1000);
                }}
                validationSchema={schema}
              >
                {props => {
                  const {
                    values: { email, password },
                    errors,
                    touched,
                    handleChange,
                    isValid,
                    setFieldTouched
                  } = props;
                  const change = (name: string, e: any) => {
                    e.persist();                
                    handleChange(e);
                    setFieldTouched(name, true, false);
                    setState( prevState  => ({ ...prevState,   [name]: e.target.value }));  
                  };
                  return (
                    <form style={{ width: '100%' }} onSubmit={e => {e.preventDefault();submitForm(LoginMutation)}}>
                      <TextField
                        variant="outlined"
                        margin="normal"
                        id="email"
                        fullWidth
                        name="email"
                        helperText={touched.email ? errors.email : ""}
                        error={touched.email && Boolean(errors.email)}
                        label="Email"     
                        value={email}
                        onChange={change.bind(null, "email")}
                      />
                      <TextField
                        variant="outlined"
                        margin="normal"
                        fullWidth
                        id="password"
                        name="password"
                        helperText={touched.password ? errors.password : ""}
                        error={touched.password && Boolean(errors.password)}
                        label="Password"
                        type="password"
                        value={password}
                        onChange={change.bind(null, "password")}
                      />
                      <FormControlLabel
                        control={<Checkbox value="remember" color="primary" />}
                        label="Remember me"
                      />
                      <br />
                      <Button className='button-center'
                        type="submit"
                        disabled={!isValid || !email || !password}
                      >
                        Submit</Button>
                    </form>
                  )
                }}
              </Formik>
            </div>
          )
        }
      </Mutation>
    );
}

export default LoginPage;

现在我不太明白我应该如何修改这段代码,以便在返回令牌时设置我的私有路由。

可能有一些条件语句,但如何以及在哪里? react-private-route 的 GitHub 存储库中的示例具有 isAuthenticated={!!isLoggedIn() /* this method returns true or false */}property。如何根据我的代码创建这个函数?

这里有几个 Typescript 的示例解决方案,但我不明白如何将它们与本地存储一起使用 How to rewrite the protected/private route using TypeScript and React-Router 4 and 5?

【问题讨论】:

标签: javascript reactjs typescript react-router react-router-dom


【解决方案1】:

如果你有本地存储中存储的令牌,你可以这样使用。

import { Redirect } from "react-router";
const PrivateRoute = ({ component: Component, ...props }) => {
  return (
    <Route
      {...props}
      render={innerProps =>
        localStorage.getItem("Token") ? (
          <Component {...innerProps} />
        ) : (
          <Redirect
            to={{
              pathname: "/",
              state: { from: props.location }
            }}
          />
        )
      }
    />
  );

【讨论】:

  • 如果我将它复制到我的 App.tsx 文件中,我会在组件上收到错误消息:Binding element 'Component' implicitly has an 'any' type.This is typescript
  • 这里有几个 Typescript 的示例解决方案,但我不明白如何将它们与本地存储一起使用 stackoverflow.com/questions/47747754/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-19
  • 2021-04-12
  • 2020-06-13
  • 2019-03-24
  • 1970-01-01
  • 2019-10-18
  • 2016-01-19
相关资源
最近更新 更多