【发布时间】: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