在react路由器中,我們如何構建基於認證的路由?在反應路由器中,我們如何建立基於認證的路由?
假設我們希望某些路由需要特定的身份驗證,比方說authTypeA,才能訪問,有些路由需要更多的身份驗證,比如說authTypeA,authTypeB,authTypeC。
那麼我們如何才能使這些在反應路由器(v2)?
在react路由器中,我們如何構建基於認證的路由?在反應路由器中,我們如何建立基於認證的路由?
假設我們希望某些路由需要特定的身份驗證,比方說authTypeA,才能訪問,有些路由需要更多的身份驗證,比如說authTypeA,authTypeB,authTypeC。
那麼我們如何才能使這些在反應路由器(v2)?
const Routes = (
<Route path="/" component={App}>
<Route component={requireAuth(['authenticated'], ['/trade'])}>
<Route path="/dualview" component={TradingViewContainer} />
<Route path="/marketdata" component={MarketDataContainer} />
</Route>
<Route path="/signin" component={SigninContainer} />
</Route>
);
我們可以使用HOC(高階組件)來建立基於驗證的路由,它在檢查驗證後管理對路徑的訪問。
在反應路由器v2中,您可以在具有驗證邏輯的高階組件中定義。
export default function(strategies = [], greenRoute = []) {
class Authentication extends Component {
constructor() {
super()
this.state = { allGreen: true }
}
componentWillMount() { // When access the route with first time
const { history, location } = this.props
if (greenRoute.indexOf(location.pathname) === -1) {
strategies.map((strategy) => {
if (!this.props.auth[strategy]) {
this.setState({ allGreen: false })
history.replace(`signin?next=${location.pathname.slice(1)}`)
}
})
}
}
componentWillUpdate(nextProps) {
const { history, auth } = this.props
if (greenRoute.indexOf(location.pathname) === -1) {
strategies.map((strategy) => {
if (!nextProps.auth[strategy]) {
this.setState({ allGreen: false })
alert(I18n.t('auth.needSignin'))
history.replace(`signin?next=${location.pathname.slice(1)}`)
}
})
}
}
shouldComponentUpdate(prevProps, prevState) {
const { location } = this.props
if (prevProps.location !== location) {
return true;
}
for (var i = 0; i < strategies.length; i++) {
return prevProps.auth[strategies[i]] !== this.props.auth[strategies[i]]
}
}
render() {
return this.state.allGreen ? this.props.children : (<div></div>)
}
}
function mapStateToProps(state) {
return {
auth: state.auth
}
}
return connect(mapStateToProps)(Authentication)
}
上面的代碼,你可以做一個邏輯,當this.state.allGreen是真的,那麼渲染this.props.children要訪問該組件。
在requireAuth組分(HOC),componentWillMount將打破在訪問其需要進行認證的特定成分,並檢查它是否具有認證狀態,然後再決定是否要被訪問或沒有。
而且,當認證狀態改變時,可以使用組件更新,以便訪問組件將被拒絕。
shouldComponentUpdate將用於表現。
此代碼建立在庫反應,反應路由器,redux上。
隨意使用!
在react-router中,可以給出一個在進入路由之前運行的函數。在那裏,你可以在出現問題的情況下進行驗證和重定向。檢查這個例子。希望它回答你
import React from 'react';
import { IndexRoute, Route, Redirect } from 'react-router';
import App from './App';
import { getToken } from './main/services/cookie';
import Navigation from './main/navigation/Navigation';
import * as authenticationActions from './authentication/actions/authenticationActions';
export default (store) => {
const performAuth = async (nextState, replace, callback) => {
const authenticated = store.getState().authentication.authenticated;
const token = getToken();
if (!authenticated) {
await store.dispatch(authenticationActions.authenticate(token));
}
callback();
};
const requireAuth = (nextState, replace) => {
const authenticated = store.getState().authentication.authenticated;
if (!authenticated) {
replace({ pathname: Navigation('login') });
}
};
const checkAuth = (nextState, replace) => {
const authenticated = store.getState().authentication.authenticated;
if (authenticated) {
replace({ pathname: Navigation('schedule') });
}
};
const languages = ['en', 'fr'];
return (
<Route onEnter={performAuth}>
<Route path="/" component={App} >
<IndexRoute component={Login} onEnter={checkAuth} />
<Route path={Navigation('login', language)} component={Login} onEnter={checkAuth} />
<Route path={Navigation('schedule', language)} component={PersonalSchedule} onEnter={requireAuth} />
<Route path={Navigation('profile', language)} component={Profile} onEnter={requireAuth} />
</Route>
<Redirect from="*" to="/" />
</Route>
);
};