Próbowałem zaimplementować uwierzytelnione trasy, ale okazało się, że React Router 4 teraz uniemożliwia to działanie:
<Route exact path="/" component={Index} />
<Route path="/auth" component={UnauthenticatedWrapper}>
<Route path="/auth/login" component={LoginBotBot} />
</Route>
<Route path="/domains" component={AuthenticatedWrapper}>
<Route exact path="/domains" component={DomainsIndex} />
</Route>
Błąd:
Ostrzeżenie: nie należy używać
<Route component>
i<Route children>
na tej samej trasie;<Route children>
zostanie zignorowany
W takim razie, jaki jest właściwy sposób realizacji tego?
Pojawia się w react-router
dokumentach (v4), sugeruje coś takiego
<Router>
<div>
<AuthButton/>
<ul>
<li><Link to="/public">Public Page</Link></li>
<li><Link to="/protected">Protected Page</Link></li>
</ul>
<Route path="/public" component={Public}/>
<Route path="/login" component={Login}/>
<PrivateRoute path="/protected" component={Protected}/>
</div>
</Router>
Ale czy można to osiągnąć, grupując razem kilka tras?
AKTUALIZACJA
Ok, po kilku badaniach wpadłem na to:
import React, {PropTypes} from "react"
import {Route} from "react-router-dom"
export default class AuthenticatedRoute extends React.Component {
render() {
if (!this.props.isLoggedIn) {
this.props.redirectToLogin()
return null
}
return <Route {...this.props} />
}
}
AuthenticatedRoute.propTypes = {
isLoggedIn: PropTypes.bool.isRequired,
component: PropTypes.element,
redirectToLogin: PropTypes.func.isRequired
}
Właściwe jest wysyłanie w render()
nim akcji , wydaje się złe. To naprawdę nie wydaje się poprawne z componentDidMount
jakimś innym hakiem?
javascript
reactjs
react-router
react-router-v4
Jiew Meng
źródło
źródło
componentWillMount
, czy kiedykolwiek będzie mógł zobaczyć renderowane wyjście nawet przez ułamek sekundy?componentWillMount()
to nie jest wezwane do SSR, to jest to,componentDidMount()
że nie jest wezwane. jakcomponentWillMount()
nazywano wcześniejrender()
, więc użytkownik nie zobaczy niczego nowego komponentu. więc jest to najlepsze miejsce do sprawdzenia.<Redirect to="/auth">
z dokumentacji zamiast wywoływać akcję wysyłkiOdpowiedzi:
Będziesz chciał użyć
Redirect
komponentu. Istnieje kilka różnych podejść do tego problemu. Oto jeden, który mi się podoba, mam komponent PrivateRoute, który pobieraauthed
prop, a następnie renderuje na podstawie tych rekwizytów.Teraz twoje
Route
s mogą wyglądać mniej więcej takJeśli nadal jesteś zdezorientowany, napisałem ten post, który może pomóc - Chronione trasy i uwierzytelnianie za pomocą React Router v4
źródło
<Redirect />
. Problem w tym,<Redirect />
że wydaje się, że nie działa z Redux w moim przypadku? Muszę wysłać akcjęstate: {from: props.location}}}
spowodowałomaximum call stack exceeded
. Musiałem to usunąć. Czy możesz wyjaśnić, dlaczego ta opcja jest przydatna @Tyler McGinnis?({component: Component, ...rest})
składnię. Miałem to samo pytanie lol! stackoverflow.com/a/43484565/6502003Tnx Tyler McGinnis za rozwiązanie. Mój pomysł zrodził się z pomysłu Tylera McGinnisa.
Możesz to zaimplementować w ten sposób
DecisionFunc tylko funkcja, która zwraca prawdę lub fałsz
źródło
(Używanie Redux do zarządzania stanem)
Jeśli użytkownik spróbuje uzyskać dostęp do dowolnego adresu URL, najpierw sprawdzę, czy token dostępu jest dostępny, jeśli nie przekieruje do strony logowania. Gdy użytkownik zaloguje się za pomocą strony logowania, przechowujemy go w magazynie lokalnym, a także w naszym stanie redux. (Localstorage lub cookies… na razie trzymamy ten temat poza kontekstem).
ponieważ stan Redux jako zaktualizowany, a prywatne trasy zostaną ponownie wyrenderowane. teraz mamy token dostępu, więc przekierujemy na stronę główną.
Przechowuj również zdekodowane dane ładunku autoryzacji w stanie redux i przekaż je do kontekstu reakcji. (Nie musimy używać kontekstu, ale aby uzyskać dostęp do autoryzacji w dowolnym z naszych zagnieżdżonych komponentów podrzędnych, ułatwia to dostęp z kontekstu zamiast łączenia każdego komponentu podrzędnego z reduxem).
Wszystkie trasy, które nie wymagają specjalnych ról, można uzyskać bezpośrednio po zalogowaniu .. Jeśli potrzebna jest rola, np. Admin (stworzyliśmy chronioną trasę, która sprawdza, czy miał pożądaną rolę, jeśli nie przekierowuje do nieautoryzowanego komponentu)
podobnie w każdym komponencie, jeśli musisz wyłączyć przycisk lub coś w oparciu o rolę.
po prostu możesz to zrobić w ten sposób
A co, jeśli użytkownik spróbuje wstawić fikcyjny token w localstorage. Ponieważ mamy token dostępu, przekierujemy do komponentu domowego. Mój komponent domowy wykona wywołanie rest w celu pobrania danych, ponieważ token jwt był fikcyjny, wywołanie rest zwróci nieautoryzowanego użytkownika. Więc wywołuję wylogowanie (co wyczyści localstorage i ponownie przekieruje do strony logowania). Jeśli strona główna ma dane statyczne i nie wykonuje żadnych wywołań API (wtedy powinieneś mieć wywołanie api token-weryfikacja w zapleczu, abyś mógł sprawdzić, czy token jest PRAWDZIWY przed załadowaniem strony głównej)
index.js
History.js
Privateroutes.js
checkAuth.js
ODKODOWANA PRÓBKA TOKENU JWT
źródło
Signin
? Jeśli użytkownik wie, że nie jest zalogowany, powinien mieć możliwość bezpośredniego dostępu do Signin, prawda?zainstaluj respond-router-dom
następnie utwórz dwa komponenty, jeden dla prawidłowych użytkowników, a drugi dla nieprawidłowych użytkowników.
spróbuj tego na app.js
źródło
Na podstawie odpowiedzi @Tyler McGinnis . Zrobiłem inne podejście, używając składni ES6 i zagnieżdżonych tras z opakowanymi komponentami:
I używając go:
źródło
Wiem, że minęło trochę czasu, ale pracowałem nad pakietem npm dla tras prywatnych i publicznych.
Oto jak utworzyć prywatną trasę:
Możesz także utworzyć trasy publiczne, do których dostęp ma tylko nieuprawniony użytkownik
Mam nadzieję, że to pomoże!
źródło
Wdrożyłem za pomocą
uwierzytelnione właściwości zostaną przekazane do komponentów, np. rejestracja, za pomocą której można zmienić stan użytkownika. Kompletne trasy AppRoutes
Sprawdź cały projekt tutaj: https://github.com/varunon9/hello-react
źródło
Wygląda na to, że wahasz się przy tworzeniu własnego komponentu, a następnie wysyłaniu go metodą renderowania? Cóż, możesz uniknąć obu, po prostu używając
render
metody<Route>
komponentu. Nie ma potrzeby tworzenia<AuthenticatedRoute>
komponentu, chyba że naprawdę chcesz. Może to być tak proste, jak poniżej. Zwróć uwagę na{...routeProps}
rozkładówkę, upewniając się, że nadal wysyłasz właściwości<Route>
komponentu do komponentu podrzędnego (<MyComponent>
w tym przypadku).Zobacz dokumentację renderowania React Router V4
Jeśli chciałeś stworzyć dedykowany komponent, wygląda na to, że jesteś na dobrej drodze. Ponieważ React Router V4 jest czysto deklaratywnym routingiem (tak jest napisane w opisie), nie sądzę, że wyjdzie ci na sucho umieszczenie kodu przekierowania poza normalnym cyklem życia komponentu. Patrząc na kod samego routera React , wykonują przekierowanie w albo
componentWillMount
lubcomponentDidMount
w zależności od tego, czy jest to strona renderowania serwera. Oto poniższy kod, który jest dość prosty i może pomóc Ci poczuć się bardziej komfortowo z miejscem, w którym należy umieścić logikę przekierowania.źródło
Moja poprzednia odpowiedź nie jest skalowalna. Oto, co uważam za dobre podejście:
Twoje trasy
Pomysł polega na użyciu opakowania w
component
właściwościach, które zwróciłoby oryginalny komponent, gdyby nie było wymagane uwierzytelnianie lub zostało już uwierzytelnione, w przeciwnym razie zwróciłoby domyślny komponent, np. Login.źródło
Oto prosta, czysta, chroniona trasa
isTokenVerified
to wywołanie metody sprawdzającej token autoryzacji, w zasadzie zwraca wartość logiczną.źródło
Oto, jak rozwiązałem to za pomocą React i Typescript. Mam nadzieję, że to pomoże !
źródło
źródło
Szukałem też odpowiedzi. Tutaj wszystkie odpowiedzi są całkiem dobre, ale żadna z nich nie daje odpowiedzi, jak możemy z niej skorzystać, jeśli użytkownik uruchomi aplikację po ponownym otwarciu. (Miałem na myśli wspólne używanie ciasteczek).
Nie ma potrzeby tworzenia nawet innego komponentu privateRoute. Poniżej znajduje się mój kod
A oto authComponent
Poniżej napisałem bloga, możesz tam również uzyskać bardziej szczegółowe wyjaśnienia.
Twórz chronione trasy w ReactJS
źródło
Rozwiązanie, które ostatecznie działało najlepiej dla mojej organizacji, jest szczegółowo opisane poniżej, po prostu dodaje sprawdzenie renderowania dla trasy sysadmin i przekierowuje użytkownika do innej głównej ścieżki aplikacji, jeśli nie mogą przebywać na stronie.
SysAdminRoute.tsx
Istnieją 3 główne trasy dla naszej implementacji, publiczna strona / witryna, zalogowany klient / aplikacja i narzędzia administratora sys w / sysadmin. Zostaniesz przekierowany na podstawie Twojej „autoryzacji” i to jest strona w / sysadmin.
SysAdminNav.tsx
źródło