React Router 4에서 인증된 루트를 구현하려면 어떻게 해야 합니까?
인증된 루트를 구현하려고 했는데 React Router 4가 이 기능을 하지 못하게 되었습니다.
<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>
에러는 다음과 같습니다.
경고:사용해서는 안 됩니다.
<Route component>
★★★★★★★★★★★★★★★★★」<Route children>
<Route children>
이 경우 올바른 구현 방법은 무엇입니까?
.react-router
(v4) 문서와 같은 합니다.
<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>
하지만 여러 경로를 함께 묶으면서 이를 달성할 수 있을까요?
몇 가지 조사 후, 저는 다음과 같은 것을 생각해 냈습니다.
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
}
?render()
느낌이 이상해요. 사실은 안 것 요.componentDidMount
다른 갈고리도 없고요
해서 여러분도 하시는 게 것 같아요.Redirect
에는 몇 이 문제에는 몇 가지 다른 접근법이 있다.드는 .PrivateRoute 컴포넌트는, 「PrivateRoute」를 합니다. Private Route の private private private private 。이 컴포넌트는authed
그 소품을 바탕으로 렌더링합니다.
function PrivateRoute ({component: Component, authed, ...rest}) {
return (
<Route
{...rest}
render={(props) => authed === true
? <Component {...props} />
: <Redirect to={{pathname: '/login', state: {from: props.location}}} />}
/>
)
}
당신의 ★★★★★★★★★★★★★★★★★.Route
는 이렇게 수 요.
<Route path='/' exact component={Home} />
<Route path='/login' component={Login} />
<Route path='/register' component={Register} />
<PrivateRoute authed={this.state.authed} path='/dashboard' component={Dashboard} />
아직 혼란스럽다면 도움이 될 수 있는 투고를 작성했습니다.React Router v4를 사용한 보호 경로 및 인증
모든 답변이 구식입니다.
★★★★render
의 Route
react-router-dom 설명서는 V5에서 더 이상 작동하지 않으며 V6에서는 제거되었다고 합니다.
대신 다음과 같이 동작합니다.
const RequireAuth: FC<{ children: React.ReactElement }> = ({ children }) => {
const userIsLogged = useLoginStatus(); // Your hook to get login status
if (!userIsLogged) {
return <LoginPage />;
}
return children;
};
사용방법:
/* A route that doesn't require login */
<Route
path="sign-up"
element={
<SignUpPage />
}
/>
/* A route that requires login */
<Route
path="dashboard"
element={
<RequireAuth>
<DashboardPage />
</RequireAuth>
}
/>
편집: 코드 예를 리액트 라우터의 v6로 업데이트했습니다.
Tnx Tyler McGinnis가 솔루션을 제공합니다.난 타일러 맥기니스 아이디어에서 아이디어를 얻었어
const DecisionRoute = ({ trueComponent, falseComponent, decisionFunc, ...rest }) => {
return (
<Route
{...rest}
render={
decisionFunc()
? trueComponent
: falseComponent
}
/>
)
}
이렇게 구현할 수 있습니다.
<DecisionRoute path="/signin" exact={true}
trueComponent={redirectStart}
falseComponent={SignInPage}
decisionFunc={isAuth}
/>
결정func는 true 또는 false를 반환하는 함수입니다.
const redirectStart = props => <Redirect to="/orders" />
(상태 관리에 Redx 사용)
사용자가 URL에 액세스하려고 하면 먼저 액세스 토큰을 사용할 수 있는지 확인합니다. 또는쿠키( ( ) ( ( ( 。이 토픽은, 현재로서는 문맥에 관계하지 않습니다.
되어 privateroutes가에 홈 .이제 액세스 토큰이 있으므로 홈 페이지로 리디렉션합니다.
디코딩된 인가 페이로드 데이터도 redux 상태로 저장하여 리액트 컨텍스트에 전달합니다.(콘텍스트를 사용할 필요는 없지만 네스트된 하위 컴포넌트 중 하나에서 권한 부여에 액세스하기 위해 모든 하위 컴포넌트를 redx에 연결하는 대신 컨텍스트에서 쉽게 액세스할 수 있습니다.)
특별한 역할이 필요하지 않은 모든 경로는 로그인 후 바로 액세스할 수 있습니다.admin과 같은 역할이 필요한 경우(부정 컴포넌트로 리다이렉트되지 않은 경우 원하는 역할이 있는지 여부를 체크하는 보호된 루트를 작성했습니다).
마찬가지로 버튼이나 기타 기능을 역할에 따라 비활성화해야 하는 경우 컴포넌트에서도 마찬가지입니다.
간단하게는, 이 방법으로 할 수 있다
const authorization = useContext(AuthContext);
const [hasAdminRole] = checkAuth({authorization, roleType:"admin"});
const [hasLeadRole] = checkAuth({authorization, roleType:"lead"});
<Button disable={!hasAdminRole} />Admin can access</Button>
<Button disable={!hasLeadRole || !hasAdminRole} />admin or lead can access</Button>
사용자가 로컬 스토리지에 더미 토큰을 삽입하려고 하면 어떻게 됩니까?액세스 토큰이 있기 때문에 홈 컴포넌트로 리다이렉트 합니다.jwt 토큰이 더미였기 때문에 홈 컴포넌트는 데이터를 얻기 위해 rest call을 발신합니다.rest call은 허가되지 않은 사용자를 반환합니다.로그아웃을 호출합니다(로컬 스토리지를 클리어하고 다시 로그인 페이지로 리다이렉트합니다).홈 페이지에 정적 데이터가 있고 API 호출이 없는 경우(홈 페이지를 로드하기 전에 토큰이 REAL인지 확인할 수 있도록 백엔드에 token-verify api 호출이 있어야 합니다).
index.displaces를 표시합니다.
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, Switch } from 'react-router-dom';
import history from './utils/history';
import Store from './statemanagement/store/configureStore';
import Privateroutes from './Privateroutes';
import Logout from './components/auth/Logout';
ReactDOM.render(
<Store>
<Router history={history}>
<Switch>
<Route path="/logout" exact component={Logout} />
<Route path="/" exact component={Privateroutes} />
<Route path="/:someParam" component={Privateroutes} />
</Switch>
</Router>
</Store>,
document.querySelector('#root')
);
History.js
import { createBrowserHistory as history } from 'history';
export default history({});
개인 정보입니다.js
import React, { Fragment, useContext } from 'react';
import { Route, Switch, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import { AuthContext, checkAuth } from './checkAuth';
import App from './components/App';
import Home from './components/home';
import Admin from './components/admin';
import Login from './components/auth/Login';
import Unauthorized from './components/Unauthorized ';
import Notfound from './components/404';
const ProtectedRoute = ({ component: Component, roleType, ...rest })=> {
const authorization = useContext(AuthContext);
const [hasRequiredRole] = checkAuth({authorization, roleType});
return (
<Route
{...rest}
render={props => hasRequiredRole ?
<Component {...props} /> :
<Unauthorized {...props} /> }
/>)};
const Privateroutes = props => {
const { accessToken, authorization } = props.authData;
if (accessToken) {
return (
<Fragment>
<AuthContext.Provider value={authorization}>
<App>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/login" render={() => <Redirect to="/" />} />
<Route exact path="/home" component={Home} />
<ProtectedRoute
exact
path="/admin"
component={Admin}
roleType="admin"
/>
<Route path="/404" component={Notfound} />
<Route path="*" render={() => <Redirect to="/404" />} />
</Switch>
</App>
</AuthContext.Provider>
</Fragment>
);
} else {
return (
<Fragment>
<Route exact path="/login" component={Login} />
<Route exact path="*" render={() => <Redirect to="/login" />} />
</Fragment>
);
}
};
// my user reducer sample
// const accessToken = localStorage.getItem('token')
// ? JSON.parse(localStorage.getItem('token')).accessToken
// : false;
// const initialState = {
// accessToken: accessToken ? accessToken : null,
// authorization: accessToken
// ? jwtDecode(JSON.parse(localStorage.getItem('token')).accessToken)
// .authorization
// : null
// };
// export default function(state = initialState, action) {
// switch (action.type) {
// case actionTypes.FETCH_LOGIN_SUCCESS:
// let token = {
// accessToken: action.payload.token
// };
// localStorage.setItem('token', JSON.stringify(token))
// return {
// ...state,
// accessToken: action.payload.token,
// authorization: jwtDecode(action.payload.token).authorization
// };
// default:
// return state;
// }
// }
const mapStateToProps = state => {
const { authData } = state.user;
return {
authData: authData
};
};
export default connect(mapStateToProps)(Privateroutes);
checkAuth.js
import React from 'react';
export const AuthContext = React.createContext();
export const checkAuth = ({ authorization, roleType }) => {
let hasRequiredRole = false;
if (authorization.roles ) {
let roles = authorization.roles.map(item =>
item.toLowerCase()
);
hasRequiredRole = roles.includes(roleType);
}
return [hasRequiredRole];
};
복호화 JWT 토큰 샘플
{
"authorization": {
"roles": [
"admin",
"operator"
]
},
"exp": 1591733170,
"user_id": 1,
"orig_iat": 1591646770,
"email": "hemanthvrm@stackoverflow",
"username": "hemanthvrm"
}
const Root = ({ session }) => {
const isLoggedIn = session && session.getCurrentUser
return (
<Router>
{!isLoggedIn ? (
<Switch>
<Route path="/signin" component={<Signin />} />
<Redirect to="/signin" />
</Switch>
) : (
<Switch>
<Route path="/" exact component={Home} />
<Route path="/about" component={About} />
<Route path="/something-else" component={SomethingElse} />
<Redirect to="/" />
</Switch>
)}
</Router>
)
}
리액트 컨트롤 돔을 설치하다
다음으로 유효한 사용자용 컴포넌트와 비활성 사용자용 컴포넌트를 2개 만듭니다.
app.http로 시험해 보세요.
import React from 'react';
import {
BrowserRouter as Router,
Route,
Link,
Switch,
Redirect
} from 'react-router-dom';
import ValidUser from "./pages/validUser/validUser";
import InValidUser from "./pages/invalidUser/invalidUser";
const loggedin = false;
class App extends React.Component {
render() {
return (
<Router>
<div>
<Route exact path="/" render={() =>(
loggedin ? ( <Route component={ValidUser} />)
: (<Route component={InValidUser} />)
)} />
</div>
</Router>
)
}
}
export default App;
@Tyler McGinnis의 답변을 기반으로 합니다.ES6 구문과 래핑된 컴포넌트를 포함한 네스트된 루트를 사용하여 다른 접근방식을 작성했습니다.
import React, { cloneElement, Children } from 'react'
import { Route, Redirect } from 'react-router-dom'
const PrivateRoute = ({ children, authed, ...rest }) =>
<Route
{...rest}
render={(props) => authed ?
<div>
{Children.map(children, child => cloneElement(child, { ...child.props }))}
</div>
:
<Redirect to={{ pathname: '/', state: { from: props.location } }} />}
/>
export default PrivateRoute
사용방법:
<BrowserRouter>
<div>
<PrivateRoute path='/home' authed={auth}>
<Navigation>
<Route component={Home} path="/home" />
</Navigation>
</PrivateRoute>
<Route exact path='/' component={PublicHomePage} />
</div>
</BrowserRouter>
리액트와 타이프스크립트로 해결한 방법이야도움이 되었으면 좋겠다!
import * as React from 'react';
import { FC } from 'react';
import { Route, RouteComponentProps, RouteProps, Redirect } from 'react-router';
const PrivateRoute: FC<RouteProps> = ({ component: Component, ...rest }) => {
if (!Component) {
return null;
}
const isLoggedIn = true; // Add your provider here
return (
<Route
{...rest}
render={(props: RouteComponentProps<{}>) => isLoggedIn ? (<Component {...props} />) : (<Redirect to={{ pathname: '/', state: { from: props.location } }} />)}
/>
);
};
export default PrivateRoute;
<PrivateRoute component={SignIn} path="/signin" />
오랜만이긴 하지만 개인 노선과 공공 노선의 npm 패키지를 만들고 있습니다.
프라이빗 루트를 작성하는 방법은 다음과 같습니다.
<PrivateRoute exact path="/private" authed={true} redirectTo="/login" component={Title} text="This is a private route"/>
또한 자동 사용자만 접근할 수 있는 퍼블릭루트를 만들 수도 있습니다.
<PublicRoute exact path="/public" authed={false} redirectTo="/admin" component={Title} text="This route is for unauthed users"/>
도움이 됐으면 좋겠네요!
다음을 사용하여 구현했습니다.
<Route path='/dashboard' render={() => (
this.state.user.isLoggedIn ?
(<Dashboard authenticate={this.authenticate} user={this.state.user} />) :
(<Redirect to="/login" />)
)} />
인증 소품은 사용자 상태를 변경할 수 있는 등록과 같은 구성요소로 전달됩니다.AppRoutes를 완료합니다.
import React from 'react';
import { Switch, Route } from 'react-router-dom';
import { Redirect } from 'react-router';
import Home from '../pages/home';
import Login from '../pages/login';
import Signup from '../pages/signup';
import Dashboard from '../pages/dashboard';
import { config } from '../utils/Config';
export default class AppRoutes extends React.Component {
constructor(props) {
super(props);
// initially assuming that user is logged out
let user = {
isLoggedIn: false
}
// if user is logged in, his details can be found from local storage
try {
let userJsonString = localStorage.getItem(config.localStorageKey);
if (userJsonString) {
user = JSON.parse(userJsonString);
}
} catch (exception) {
}
// updating the state
this.state = {
user: user
};
this.authenticate = this.authenticate.bind(this);
}
// this function is called on login/logout
authenticate(user) {
this.setState({
user: user
});
// updating user's details
localStorage.setItem(config.localStorageKey, JSON.stringify(user));
}
render() {
return (
<Switch>
<Route exact path='/' component={Home} />
<Route exact path='/login' render={() => <Login authenticate={this.authenticate} />} />
<Route exact path='/signup' render={() => <Signup authenticate={this.authenticate} />} />
<Route path='/dashboard' render={() => (
this.state.user.isLoggedIn ?
(<Dashboard authenticate={this.authenticate} user={this.state.user} />) :
(<Redirect to="/login" />)
)} />
</Switch>
);
}
}
프로젝트 전체를 확인하려면 여기를 클릭해 주세요.https://github.com/varunon9/hello-react
수락된 답변은 좋지만, URL의 변경을 반영하기 위해 컴포넌트가 필요할 때 문제가 해결되지 않습니다.
예를 들어 컴포넌트의 코드는 다음과 같습니다.
export const Customer = (props) => {
const history = useHistory();
...
}
URL을 변경합니다.
const handleGoToPrev = () => {
history.push(`/app/customer/${prevId}`);
}
구성 요소가 다시 로드되지 않습니다!
더 나은 솔루션:
import React from 'react';
import { Redirect, Route } from 'react-router-dom';
import store from '../store/store';
export const PrivateRoute = ({ component: Component, ...rest }) => {
let isLoggedIn = !!store.getState().data.user;
return (
<Route {...rest} render={props => isLoggedIn
? (
<Component key={props.match.params.id || 'empty'} {...props} />
) : (
<Redirect to={{ pathname: '/login', state: { from: props.location } }} />
)
} />
)
}
사용방법:
<PrivateRoute exact path="/app/customer/:id" component={Customer} />
@fermmm의 답변은 좋지만 사용자가 로그인하지 않으면 렌더링된 컴포넌트가 url과 일치하지 않습니다.그래서 방문자에게 혼란스러울 수 있다.
그래서 대신
return (
<Route {...props}>{userIsLogged ? props.children : <LoginPage/>}</Route>
);
다음을 사용하는 것이 좋습니다.
return (
<Route {...props}>
{userIsLogged ? (
props.children
) : (
<Redirect
to={{
pathname: "/login",
state: { from: location },
}}
/>
)}
</Route>
);
이 경우 이전 루트 세그먼트가 아닌 URL에서 컴포넌트가 렌더링되지만 "/login"이 됩니다.
당신은 자신의 컴포넌트를 만들고 나서 렌더 방식으로 디스패치하는 것을 주저하고 있는 것 같습니다.둘 다 피할 수 있습니다.render
의 방법<Route>
요소.를 생성할 필요가 없습니다.<AuthenticatedRoute>
컴포넌트를 사용할 수 있습니다.다음과 같이 간단하게 할 수 있습니다.주의:{...routeProps}
의 속성을 계속 전송하도록 합니다.<Route>
컴포넌트부터 자 컴포함)<MyComponent>
(이 경우)를 참조해 주세요.
<Route path='/someprivatepath' render={routeProps => {
if (!this.props.isLoggedIn) {
this.props.redirectToLogin()
return null
}
return <MyComponent {...routeProps} anotherProp={somevalue} />
} />
React Router V4 렌더 매뉴얼을 참조하십시오.
전용 컴포넌트를 작성하려면 올바른 방향으로 가고 있는 것 같습니다.React Router V4는 순전히 선언형 라우팅이기 때문에(설명에는 그렇게 되어 있습니다), 리다이렉트코드를 통상 컴포넌트의 라이프 사이클 밖에 두는 것으로는 충분치 않다고 생각합니다.리액트 라우터 자체의 코드를 보면 다음 중 하나로 리다이렉트를 수행합니다.componentWillMount
또는componentDidMount
서버 측 렌더링 여부에 따라 달라집니다.아래 코드는 매우 간단하며 리다이렉트 로직을 어디에 배치해야 하는지 쉽게 알 수 있습니다.
import React, { PropTypes } from 'react'
/**
* The public API for updating the location programatically
* with a component.
*/
class Redirect extends React.Component {
static propTypes = {
push: PropTypes.bool,
from: PropTypes.string,
to: PropTypes.oneOfType([
PropTypes.string,
PropTypes.object
])
}
static defaultProps = {
push: false
}
static contextTypes = {
router: PropTypes.shape({
history: PropTypes.shape({
push: PropTypes.func.isRequired,
replace: PropTypes.func.isRequired
}).isRequired,
staticContext: PropTypes.object
}).isRequired
}
isStatic() {
return this.context.router && this.context.router.staticContext
}
componentWillMount() {
if (this.isStatic())
this.perform()
}
componentDidMount() {
if (!this.isStatic())
this.perform()
}
perform() {
const { history } = this.context.router
const { push, to } = this.props
if (push) {
history.push(to)
} else {
history.replace(to)
}
}
render() {
return null
}
}
export default Redirect
이전 답변은 측정할 수 없습니다.여기 좋은 방법이 있습니다.
고객님의 루트-
<Switch>
<Route
exact path="/"
component={matchStateToProps(InitialAppState, {
routeOpen: true // no auth is needed to access this route
})} />
<Route
exact path="/profile"
component={matchStateToProps(Profile, {
routeOpen: false // can set it false or just omit this key
})} />
<Route
exact path="/login"
component={matchStateToProps(Login, {
routeOpen: true
})} />
<Route
exact path="/forgot-password"
component={matchStateToProps(ForgotPassword, {
routeOpen: true
})} />
<Route
exact path="/dashboard"
component={matchStateToProps(DashBoard)} />
</Switch>
입니다.component
인증이 필요 없거나 이미 인증된 경우 원래 구성요소를 반환하는 소품. 그렇지 않으면 기본 구성요소를 반환한다.
const matchStateToProps = function(Component, defaultProps) {
return (props) => {
let authRequired = true;
if (defaultProps && defaultProps.routeOpen) {
authRequired = false;
}
if (authRequired) {
// check if loginState key exists in localStorage (Your auth logic goes here)
if (window.localStorage.getItem(STORAGE_KEYS.LOGIN_STATE)) {
return <Component { ...defaultProps } />; // authenticated, good to go
} else {
return <InitialAppState { ...defaultProps } />; // not authenticated
}
}
return <Component { ...defaultProps } />; // no auth is required
};
};
이것은 간단한 청정 보호 경로입니다.
const ProtectedRoute
= ({ isAllowed, ...props }) =>
isAllowed
? <Route {...props}/>
: <Redirect to="/authentificate"/>;
const _App = ({ lastTab, isTokenVerified })=>
<Switch>
<Route exact path="/authentificate" component={Login}/>
<ProtectedRoute
isAllowed={isTokenVerified}
exact
path="/secrets"
component={Secrets}/>
<ProtectedRoute
isAllowed={isTokenVerified}
exact
path="/polices"
component={Polices}/>
<ProtectedRoute
isAllowed={isTokenVerified}
exact
path="/grants" component={Grants}/>
<Redirect from="/" to={lastTab}/>
</Switch>
isTokenVerified
는 기본적으로 부울을 반환하는 인가 토큰을 체크하기 위한 메서드콜입니다
이는 전문 레덕스 개발자가 아닌 초보자를 위한 기본적인 접근법입니다.
import React, { useState, useEffect } from "react";
import {
Route,
BrowserRouter as Router,
Switch,
Redirect,
} from "react-router-dom";
import Home from "./components/Home";
import Dashboard from "./components/Dashboard";
import Login from "./components/Login";
function App() {
const [isAuth, setAuth] = useState(false);
const checkAuth = () => {
// Your auth logic here
setAuth(true);
};
useEffect(() => {
checkAuth();
});
return (
<Router>
<Switch>
<Route
path="/user/dashboard"
render={(props) =>
isAuth ? <Dashboard {...props} /> : <Redirect to="/" />
}
/>
<Route path="/login" component={Login} />
<Route path="/" component={Home} />
</Switch>
</Router>
);
}
저만의 접근법이 있습니다.
const RedirectionUnit = () => {
const [user] = useContext(AuthContext);
const pathname = useLocation().pathname;
let redirectTo;
if (user === null) redirectTo = "login";
else if (pathname === "/")
if (user.type === "supervisor" ) redirectTo = "all-parteners";
else if (user.type === "manager" ) redirectTo = "all-employees";
else if (user.type === "employee" ) redirectTo = "unfinished-tasks";
if (redirectTo && '/' + redirectTo !== pathname)
return <Redirect to={redirectTo} />;
return null;
};
const NavigationRoutes = () => {
return (
<>
<Route component={RedirectionUnit} />
{/* prettier-ignore */}
<Switch>
<Route exact path="/login" component={Login} />
<Route exact path="/logout" component={Logout} />
<Route exact path="/new-parteners" component={NewParteners} />
<Route exact path="/all-parteners" component={AllParteners} />
<Route exact path="/new-employees" component={NewEmployees} />
<Route exact path="/all-employees" component={AllEmployees} />
<Route exact path="/unfinished-tasks" component={UnfinishedTasks} />
<Route exact path="/finished-tasks" component={FinishedTasks} />
<Route exact path="/finished-tasks" component={FinishedTasks} />
<Route component={NotFound} />
</Switch>
</>
);
};
메인 라우터 파일에 루트 인증에 필요한 모든 것이 포함되어 있는 솔루션을 찾고 있었습니다.네스트된 컴포넌트가 필요없거나 복잡한 컴포넌트일 경우.이하가 나의 접근법이다.
import React from "react";
import { Routes, Route } from "react-router-dom";
import { Navigate } from "react-router-dom";
// Other imports
export default function AppRoutes() {
// This coming from react-redux
// After a user is logged in this will set in the global state
const { currentUser } = useCurrentUser();
const landing = <Landing />
const authenticate = (component) => {
return currentUser ? component : <Navigate to="/" />;
}
return (
<Routes>
<Route path="/" element={currentUser ? <Home /> : landing} />
<Route path="/blogs/:id" element={authenticate(<Blog />)} />
<Route path="/blogs/:id/edit" element={authenticate(<BlogEdit />)} />
<Route path="/profile" element={authenticate(<Profile />)} />
<Route path="*" element={<Navigate to="/" />} />
</Routes>
);
}
@MaxThom for TypeScript 솔루션을 기반으로 컴포넌트 또는 렌더 함수를 PrivateRoute에 전달할 수 있는 옵션이 있습니다.
import React from "react";
import { Route, Redirect, RouteProps, RouteComponentProps } from "react-router-dom";
const PrivateRoute: React.FC<RouteProps> = ({component, render, ...rest}) => {
const userIsLogged = window.localStorage.getItem('currentUsecase');
if (userIsLogged === undefined) return (
<Route render={
(props: RouteComponentProps<{}>) => <Redirect
to={{ pathname: '/', state: { from: props.location } }}
/>
}/>
)
return (
<Route {...rest} render={render} component={component} />
)
};
export default PrivateRoute;
이게 도움이 됐으면 좋겠어요.
나도 답을 찾고 있었어.여기에서는 모든 답변이 매우 좋지만, 사용자가 애플리케이션을 다시 연 후 어떻게 사용할 수 있는지에 대한 답변은 없습니다.(쿠키 같이 쓰자는 거였어요)
다른 privateRoute 컴포넌트를 작성할 필요가 없습니다.아래는 내 코드입니다.
import React, { Component } from 'react';
import { Route, Switch, BrowserRouter, Redirect } from 'react-router-dom';
import { Provider } from 'react-redux';
import store from './stores';
import requireAuth from './components/authentication/authComponent'
import SearchComponent from './components/search/searchComponent'
import LoginComponent from './components/login/loginComponent'
import ExampleContainer from './containers/ExampleContainer'
class App extends Component {
state = {
auth: true
}
componentDidMount() {
if ( ! Cookies.get('auth')) {
this.setState({auth:false });
}
}
render() {
return (
<Provider store={store}>
<BrowserRouter>
<Switch>
<Route exact path="/searchComponent" component={requireAuth(SearchComponent)} />
<Route exact path="/login" component={LoginComponent} />
<Route exact path="/" component={requireAuth(ExampleContainer)} />
{!this.state.auth && <Redirect push to="/login"/> }
</Switch>
</BrowserRouter>
</Provider>);
}
}
}
export default App;
여기 auth Component가 있습니다.
import React from 'react';
import { withRouter } from 'react-router';
import * as Cookie from "js-cookie";
export default function requireAuth(Component) {
class AuthenticatedComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
auth: Cookie.get('auth')
}
}
componentDidMount() {
this.checkAuth();
}
checkAuth() {
const location = this.props.location;
const redirect = location.pathname + location.search;
if ( ! Cookie.get('auth')) {
this.props.history.push(`/login?redirect=${redirect}`);
}
}
render() {
return Cookie.get('auth')
? <Component { ...this.props } />
: null;
}
}
return withRouter(AuthenticatedComponent)
}
블로그를 작성했습니다만, 거기서도 보다 상세한 설명을 얻을 수 있습니다.
언급URL : https://stackoverflow.com/questions/43164554/how-to-implement-authenticated-routes-in-react-router-4
'programing' 카테고리의 다른 글
JDBC 연결을 가져올 수 없습니다. (0) | 2023.03.13 |
---|---|
공백 문자는 JSON에서 중요하지 않습니까? (0) | 2023.03.13 |
반응에서 여러 줄 텍스트 문자열을 렌더링하는 방법 (0) | 2023.03.13 |
React.createElement' children 파라미터 사용방법(jsx 없음) (0) | 2023.03.08 |
AngularJS - ng-repeat에 의해 생성된 라디오 버튼 선택 시 모델이 업데이트되지 않음 (0) | 2023.03.08 |