Aktualizacja (16 sierpnia 2019 r.)
W React-router v4 i korzystaniu z React Hooks wygląda to trochę inaczej. Zacznijmy od twojego 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>
);
}
Używamy Auth
biblioteki, aby sprawdzić, czy użytkownik jest aktualnie uwierzytelniony. Zastąp to funkcją sprawdzania autoryzacji. Jeśli tak, ustawiamy isAuthenticated
flagę na true
. Robimy to po pierwszym załadowaniu naszej aplikacji. Warto również wspomnieć, że możesz chcieć dodać znak ładowania do swojej aplikacji podczas sprawdzania autoryzacji, aby nie flashować strony logowania za każdym razem, gdy odświeżasz stronę.
Następnie przekazujemy flagę na nasze trasy. Tworzymy dwa rodzaje tras AuthenticatedRoute
i UnauthenticatedRoute
.
Do AuthenticatedRoute.js
wygląda następująco.
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}`}
/>}
/>
);
}
Sprawdza, czy isAuthenticated
jest ustawiona na true
. Jeśli tak, wyrenderuje żądany komponent. Jeśli nie, przekieruje do strony logowania.
Z UnauthenticatedRoute.js
drugiej strony tak wygląda.
export default ({ component: C, appProps, ...rest }) =>
<Route
{...rest}
render={props =>
!appProps.isAuthenticated
? <C {...props} {...appProps} />
: <Redirect to="/" />}
/>;
W tym przypadku, jeśli isAuthenticated
jest ustawiona na false
, wyrenderuje żądany komponent. A jeśli jest ustawiona na true, przekieruje Cię na stronę główną.
Szczegółowe wersje tego można znaleźć w naszym przewodniku - https://serverless-stack.com/chapters/create-a-route-that-redirects.html .
Starsza wersja
Zaakceptowana odpowiedź jest prawidłowa, ale Mixins są uważane za szkodliwe ( https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html ) przez zespół React.
Jeśli ktoś napotka to pytanie i szuka zalecanego sposobu, aby to zrobić, sugerowałbym użycie komponentów wyższego rzędu zamiast miksów.
Oto przykład HOC, który sprawdza, czy użytkownik jest zalogowany przed kontynuowaniem. A jeśli użytkownik nie jest zalogowany, przekieruje Cię do strony logowania. Ten komponent przyjmuje właściwość o nazwie isLoggedIn
, która jest w zasadzie flagą, którą aplikacja może przechowywać, aby wskazać, czy użytkownik jest zalogowany.
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);
}
Aby skorzystać z tego HOC, po prostu owiń go wokół swoich tras. W przypadku twojego przykładu byłoby to:
<Route handler={requireAuth(Todos)} name="todos"/>
Omawiam to i kilka innych tematów w szczegółowym samouczku krok po kroku tutaj - https://serverless-stack.com/chapters/create-a-hoc-that-checks-auth.html