Actualización (16 de agosto de 2019)
En react-router v4 y usando React Hooks, esto se ve un poco diferente. Empecemos con tu App.js
.
export default function App() {
const [isAuthenticated, userHasAuthenticated] = useState(false);
useEffect(() => {
onLoad();
}, []);
async function onLoad() {
try {
await Auth.currentSession();
userHasAuthenticated(true);
} catch (e) {
alert(e);
}
}
return (
<div className="App container">
<h1>Welcome to my app</h1>
<Switch>
<UnauthenticatedRoute
path="/login"
component={Login}
appProps={{ isAuthenticated }}
/>
<AuthenticatedRoute
path="/todos"
component={Todos}
appProps={{ isAuthenticated }}
/>
<Route component={NotFound} />
</Switch>
</div>
);
}
Estamos usando una Auth
biblioteca para verificar si el usuario está autenticado actualmente. Reemplace esto con su función de verificación de autenticación. Si es así, establecemos la isAuthenticated
bandera en true
. Hacemos esto cuando nuestra aplicación se carga por primera vez. También vale la pena mencionar que es posible que desee agregar un signo de carga en su aplicación mientras se ejecuta la verificación de autenticación, para que no muestre la página de inicio de sesión cada vez que actualice la página.
Luego pasamos la bandera a nuestras rutas. Creamos dos tipos de rutas AuthenticatedRoute
y UnauthenticatedRoute
.
Se AuthenticatedRoute.js
ve así.
export default function AuthenticatedRoute({ component: C, appProps, ...rest }) {
return (
<Route
{...rest}
render={props =>
appProps.isAuthenticated
? <C {...props} {...appProps} />
: <Redirect
to={`/login?redirect=${props.location.pathname}${props.location.search}`}
/>}
/>
);
}
Comprueba si isAuthenticated
está configurado en true
. Si es así, renderizará el componente deseado. De lo contrario, redirigirá a la página de inicio de sesión.
El UnauthenticatedRoute.js
por otro lado se ve así.
export default ({ component: C, appProps, ...rest }) =>
<Route
{...rest}
render={props =>
!appProps.isAuthenticated
? <C {...props} {...appProps} />
: <Redirect to="/" />}
/>;
En este caso, si isAuthenticated
está configurado en false
, renderizará el componente deseado. Y si está configurado como verdadero, lo enviará a la página de inicio.
Puede encontrar versiones detalladas de esto en nuestra guía: https://serverless-stack.com/chapters/create-a-route-that-redirects.html .
Versión antigua
La respuesta aceptada es correcta, pero el equipo de React considera que los Mixins son dañinos ( https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html ).
Si alguien se encuentra con esta pregunta y está buscando la forma recomendada de hacerlo, le sugiero que use Componentes de orden superior en lugar de Mixins.
Aquí hay un ejemplo de un HOC que verificará si el usuario inició sesión antes de continuar. Y si el usuario no ha iniciado sesión, lo redireccionará a la página de inicio de sesión. Este componente toma un accesorio llamado isLoggedIn
, que es básicamente una bandera que su aplicación puede almacenar para indicar si el usuario está conectado.
import React from 'react';
import { withRouter } from 'react-router';
export default function requireAuth(Component) {
class AuthenticatedComponent extends React.Component {
componentWillMount() {
this.checkAuth();
}
checkAuth() {
if ( ! this.props.isLoggedIn) {
const location = this.props.location;
const redirect = location.pathname + location.search;
this.props.router.push(`/login?redirect=${redirect}`);
}
}
render() {
return this.props.isLoggedIn
? <Component { ...this.props } />
: null;
}
}
return withRouter(AuthenticatedComponent);
}
Y para usar este HOC, simplemente envuélvalo en sus rutas. En el caso de su ejemplo, sería:
<Route handler={requireAuth(Todos)} name="todos"/>
Cubro este y algunos otros temas en un tutorial detallado paso a paso aquí: https://serverless-stack.com/chapters/create-a-hoc-that-checks-auth.html