If my login in successful, an authentication token is returned, which is stored in the local storage. Upon successful login, I want to go the a private route.
I found this code Javascript snippet but I am unable to make it work for Typescript. I don’t have any isAuthenthicated property yet. How could I modify this accordingly?
const PrivateRoute = ({ component: Component, ...rest }) => ( <Route {...rest} render={props => ( fakeAuth.isAuthenticated ? ( <Component {...props}/> ) : ( <Redirect to={{pathname: '/login', state: { from: props.location } }}/> ) )}/> )
Here is my login screen:
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;
There is a similar question but it doesn’t answer my case since I’m storing the token in local storage.
Advertisement
Answer
This will go in your index.tsx file:
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}/>; };
And use this in the browser router/switch:
<PrivateRoute path='/panel' isAuthenticated={token} component={PrivateContainer} />