-
-
Save EduVencovsky/f8f6c275f42f7352571c92a59309e31d to your computer and use it in GitHub Desktop.
import React, { useState, useEffect } from 'react' | |
import PropTypes from 'prop-types' | |
import { checkIsAuthenticated, authSignUp, authLogin, authLogout } from '../../services/auth' | |
export const AuthContext = React.createContext({}) | |
export default function Auth({ children }) { | |
const [isAuthenticated, setIsAuthenticated] = useState(false) | |
const [isLoading, setIsLoading] = useState(true) | |
useEffect(() => { | |
checkAuth() | |
}, []) | |
const checkAuth = () => checkIsAuthenticated() | |
.then(() => setIsAuthenticated(true)) | |
.catch(() => setIsAuthenticated(false)) | |
.then(() => setIsLoading(false)) | |
const login = credentials => authLogin(credentials) | |
.then(setIsAuthenticated(true)) | |
.catch(error => { | |
alert(error) | |
setIsAuthenticated(false) | |
}) | |
const logout = () => { | |
authLogout() | |
setIsAuthenticated(false) | |
} | |
const signUp = credentials => authSignUp(credentials) | |
.then(setIsAuthenticated(true)) | |
.catch(error => { | |
alert(error) | |
setIsAuthenticated(false) | |
}) | |
return ( | |
<AuthContext.Provider value={{ isAuthenticated, isLoading, login, logout, signUp }}> | |
{children} | |
</AuthContext.Provider> | |
) | |
} | |
Auth.propTypes = { | |
children: PropTypes.oneOfType([ | |
PropTypes.func, | |
PropTypes.array | |
]) | |
} |
import React from 'react' | |
import { Switch, Route } from 'react-router-dom' | |
import PrivateRoute from './components/PrivateRoute/PrivateRoute' | |
import Auth from './components/Auth/Auth' | |
import Header from './components/Header/Header' | |
import HomePage from './views/HomePage/HomePage' | |
import SignUp from './views/SignUp/SignUp' | |
import SignIn from './views/SignIn/SignIn' | |
import FormList from './views/FormList/FormList' | |
import PageNotFound from './views/PageNotFound/PageNotFound' | |
export default function App() { | |
return ( | |
<div> | |
<Auth> | |
<Header /> | |
<Switch> | |
<Route exact path="/" component={HomePage} /> | |
<Route path="/signup" component={SignUp} /> | |
<Route path="/signin" component={SignIn} /> | |
<PrivateRoute path="/forms" component={FormList} /> | |
<Route component={PageNotFound} /> | |
</Switch> | |
</Auth> | |
</div> | |
) | |
} |
import React, { useContext } from 'react' | |
import { Route, Redirect } from 'react-router-dom' | |
import PropTypes from 'prop-types' | |
import { AuthContext } from '../Auth/Auth' | |
import Loading from '../../views/Loading/Loading' | |
const PrivateRoute = ({ component: Component, ...otherProps }) => { | |
const { isAuthenticated, isLoading } = useContext(AuthContext) | |
return ( | |
<Route | |
{...otherProps} | |
render={props => ( | |
!isLoading | |
? | |
( | |
isAuthenticated | |
? | |
<Component {...props} /> | |
: | |
<Redirect to={otherProps.redirectTo ? otherProps.redirectTo : '/signin'} /> | |
) | |
: | |
<Loading /> | |
)} | |
/> | |
) | |
} | |
PrivateRoute.propTypes = { | |
component: PropTypes.func.isRequired | |
} | |
export default PrivateRoute |
@EduVencovsky thank you for your response, I meant return user back to the sign-in page and wipe the current token, now I solve it by dispatching an action by redux to do that since the Hook Context will not be available everywhere for example (inside Axios interceptor) when I catch the 401 error of any request.
Yeah I am doing exactly the same. I use redux
solely for this purpose (Also using axios
).
There is another way, by wrapping all API calls in context and making them available through a hook or such,
but I have been trying this and it feels rather messy to be honest.
@hvolschenk Aha I see and I agree with dispatching action it's a better way than having multiple hooks traversing all these data.
thanks for the approach, well done
However, when we reload the protected route page the initial value of isAuthenticated is false and we are redirected to /signin directly ......But when isAuthenticated is set to true after some time it has no effect on the current route since we are already on '/signin'.......Correct me if i am wrong but this approach does not seem to be working for me since checking isAuthenticated is a time consuming task????
Thank You.
Thanks Sir
Where is ../../services/auth file is?
awesome, thanks sir.
Where is ../../services/auth file is?
Same i also want to see how those functions atre
async await завезли пацаны
Exactly what I've been looking for, thanks!
However, when we reload the protected route page the initial value of isAuthenticated is false and we are redirected to /signin directly ......But when isAuthenticated is set to true after some time it has no effect on the current route since we are already on '/signin'.......Correct me if i am wrong but this approach does not seem to be working for me since checking isAuthenticated is a time consuming task???? Thank You.
I have the same issue @NabinOjha did you find any solution?
@EduVencovsky what's your thought on this?
However, when we reload the protected route page the initial value of isAuthenticated is false and we are redirected to /signin directly ......But when isAuthenticated is set to true after some time it has no effect on the current route since we are already on '/signin'.......Correct me if i am wrong but this approach does not seem to be working for me since checking isAuthenticated is a time consuming task???? Thank You.
I have the same issue @NabinOjha did you find any solution? @EduVencovsky what's your thought on this?
https://medium.com/@dennisivy/creating-protected-routes-with-react-router-v6-2c4bbaf7bc1c
@EduVencovsky thank you for your response, I meant return user back to the sign-in page and wipe the current token, now I solve it by dispatching an action by redux to do that since the Hook Context will not be available everywhere for example (inside Axios interceptor) when I catch the 401 error of any request.
Regarding the checking on each private route, I think this is should be a generic case since we don't want to a user browsing the private pages while his token has been expired, that's why we need each page change for a private route to check if the token still valid that's part I didn't figure it out yet