【问题标题】:PrivateRouting when Token in Local Storage [TypeScript]本地存储中令牌时的 PrivateRouting [TypeScript]
【发布时间】:2020-06-13 22:29:32
【问题描述】:

如果我登录成功,则返回一个身份验证令牌,该令牌存储在本地存储中。成功登录后,我想走私人路线。

我找到了这段代码 Javascript sn-p 但我无法让它适用于 Typescript。我还没有任何 isAuthenthicated 属性。我该如何相应地修改它?

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={props => (
    fakeAuth.isAuthenticated ? (
      <Component {...props}/>
    ) : (
      <Redirect to={{pathname: '/login', state: { from: props.location }
   }}/>
  )
 )}/>
)

这是我的登录屏幕:

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;

有一个类似的问题,但它没有回答我的情况,因为我将令牌存储在本地存储中。

【问题讨论】:

  • 我该如何相应地修改它? 这取决于[取决于您的身份验证的工作方式]。如果令牌的存在意味着用户已经登录,那么最简单的更改是将fakeAuth.isAuthenticated更改为localStorage.token
  • 是的,我在想类似的东西:const userLoggedIn = localStorage.getItem('token'); 但是,知道如何在打字稿中完成这项工作吗? @Max
  • 在大多数情况下,您应该有某种存储(Redux、MobX 等)来保存用户的数据。然后,您只需从商店获取并随意使用即可。您所说的“我如何在打字稿中完成这项工作”是什么意思?
  • 哦,是的,我还没有添加 Redux。我先补充一下。但另一方面,我基本上使用 grpahql apollo 进行身份验证。现在 apollo 本身就是一个状态管理库。在这种情况下,我该如何使用 apollo?
  • 就个人而言,在这种情况下,我没有阿波罗缓存的最佳实践。因为对我来说,有时候,在涉及数据解析和业务逻辑的情况下使用 apollo 缓存似乎是不合理的。这些东西应该由商店(或后端)处理和持有。身份验证也可能属于该区域。虽然,我听说在 apollo 缓存旁边使用存储是不好的做法。但是,我也看过一些指南,人们说您必须使用商店并且不要完全依赖 apollo 缓存。所以一切都取决于你:)

标签: javascript reactjs typescript react-router apollo


【解决方案1】:

这将进入您的 index.tsx 文件:

const token = localStorage.getItem('token');

const PrivateRoute = ({component, isAuthenticated, ...rest}: any) => {
    const routeComponent = (props: any) => (
        isAuthenticated
            ? React.createElement(component, props)
            : <Redirect to={{pathname: '/login'}}/>
    );
    return <Route {...rest} render={routeComponent}/>;
};

并在浏览器路由器/交换机中使用它:

<PrivateRoute
    path='/panel'
    isAuthenticated={token}
    component={PrivateContainer}
/>

【讨论】:

    【解决方案2】:

    只需将 fakeAuth.isAuthenticated 替换为您保存的令牌,您也可以将其保存为全局状态,对吗?所以,一般来说,它只是一个布尔属性来检查用户是否成功登录,取决于用户将重定向到登录页面或受保护页面的情况

    【讨论】:

      猜你喜欢
      • 2021-04-12
      • 2019-03-24
      • 1970-01-01
      • 1970-01-01
      • 2017-09-22
      • 1970-01-01
      • 1970-01-01
      • 2019-10-18
      • 2018-11-12
      相关资源
      最近更新 更多