Javascript 检查是否已登录-React路由器应用程序ES6
我正在使用React路由器(v2.8.1)和ES6语法编写React.js应用程序(v15.3)。我无法获取路由器代码来拦截页面之间的所有转换,以检查用户是否需要先登录 我的顶级渲染方法非常简单(应用程序也很简单):Javascript 检查是否已登录-React路由器应用程序ES6,javascript,authentication,reactjs,ecmascript-6,react-router,Javascript,Authentication,Reactjs,Ecmascript 6,React Router,我正在使用React路由器(v2.8.1)和ES6语法编写React.js应用程序(v15.3)。我无法获取路由器代码来拦截页面之间的所有转换,以检查用户是否需要先登录 我的顶级渲染方法非常简单(应用程序也很简单): render() { 返回( ); } web上的所有示例都使用ES5代码或旧版本的react router(早于版本2),并且我对Mixin(已弃用)和WillTransitiono(从未调用)的各种尝试都失败了 如何设置全局“拦截器功能”以强制用户在登录他们请求的页面之前进行
render()
{
返回(
);
}
web上的所有示例都使用ES5代码或旧版本的react router(早于版本2),并且我对Mixin(已弃用)和WillTransitiono(从未调用)的各种尝试都失败了
如何设置全局“拦截器功能”以强制用户在登录他们请求的页面之前进行身份验证?每个路由都有一个在路由转换发生之前调用的onEnter hook。使用自定义的requireAuth函数处理onEnter钩子
<Route path="/search" component={Search} onEnter={requireAuth} />
此版本的OneNet回调最终适用于react路由器(v2.8): 解释V1和v2之间路由器重定向差异的链接是。以下引用相关章节:
Likewise, redirecting from an onEnter hook now also uses a location descriptor.
// v1.0.x
(nextState, replaceState) => replaceState(null, '/foo')
(nextState, replaceState) => replaceState(null, '/foo', { the: 'query' })
// v2.0.0
(nextState, replace) => replace('/foo')
(nextState, replace) => replace({ pathname: '/foo', query: { the: 'query' } })
下面列出的完整代码(react路由器版本2.8.1):
requireAuth(nextState,
replace)
{
if(!this.authenticated()) // pseudocode - SYNCHRONOUS function (cannot be async without extra callback parameter to this function)
replace('/login');
}
render() {
return (
<Router history={hashHistory}>
<Route path="/" component={AppMain}>
<Route path="login" component={Login}/>
<Route path="logout" component={Logout}/>
<Route path="subject" component={SubjectPanel} onEnter={this.requireAuth}/>
<Route path="all" component={NotesPanel} onEnter={this.requireAuth}/>
</Route>
</Router>
);
}
requireAuth(下一状态,
替换)
{
if(!this.authenticated())//伪代码-同步函数(如果没有此函数的额外回调参数,则不能是异步的)
替换('/login');
}
render(){
返回(
);
}
在v4中,您只需创建一个路由组件,检查使用是否经过身份验证,并返回下一个组件,当然,下一个组件可以是其他路由
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Route, Redirect } from 'react-router-dom';
import AuthMiddleware from 'modules/middlewares/AuthMiddleware';
class PrivateRoute extends Component {
static propTypes = {
component: PropTypes.func.isRequired,
isAuthenticated: PropTypes.bool,
isLoggedIn: PropTypes.func.isRequired,
isError: PropTypes.bool.isRequired
};
static defaultProps = {
isAuthenticated: false
};
constructor(props) {
super(props);
if (!props.isAuthenticated) {
setTimeout(() => {
props.isLoggedIn();
}, 5);
}
}
componentWillMount() {
if (this.props.isAuthenticated) {
console.log('authenticated');
} else {
console.log('not authenticated');
}
}
componentWillUnmount() {}
render() {
const { isAuthenticated, component, isError, ...rest } = this.props;
if (isAuthenticated !== null) {
return (
<Route
{...rest}
render={props => (
isAuthenticated ? (
React.createElement(component, props)
) : (
<Redirect
to={{
pathname: isError ? '/login' : '/welcome',
state: { from: props.location }
}}
/>
)
)}
/>
);
} return null;
}
}
const mapStateToProps = (state) => {
return {
isAuthenticated: state.auth.isAuthenticated,
isError: state.auth.isError
};
};
const mapDispatchToProps = (dispatch) => {
return bindActionCreators({
isLoggedIn: () => AuthMiddleware.isLoggedIn()
}, dispatch);
};
export default connect(mapStateToProps, mapDispatchToProps)(PrivateRoute);
import React,{Component}来自'React';
从“道具类型”导入道具类型;
从'react redux'导入{connect};
从“redux”导入{bindActionCreators};
从“react router dom”导入{Route,Redirect};
从“模块/中间件/AuthMiddleware”导入AuthMiddleware;
类PrivateRoute扩展组件{
静态类型={
组件:PropTypes.func.isRequired,
已验证:PropTypes.bool,
isLoggedIn:PropTypes.func.isRequired,
isError:PropTypes.bool.isRequired
};
静态defaultProps={
I验证:错误
};
建造师(道具){
超级(道具);
如果(!props.isAuthenticated){
设置超时(()=>{
props.isLoggedIn();
}, 5);
}
}
组件willmount(){
如果(此.props.isAuthenticated){
console.log('authenticated');
}否则{
console.log(“未验证”);
}
}
componentWillUnmount(){}
render(){
const{isAuthenticated,component,isError,…rest}=this.props;
如果(已验证!==null){
返回(
(
我被认证了(
React.createElement(组件、道具)
) : (
)
)}
/>
);
}返回null;
}
}
常量mapStateToProps=(状态)=>{
返回{
isAuthenticated:state.auth.isAuthenticated,
isError:state.auth.isError
};
};
const mapDispatchToProps=(调度)=>{
返回bindActionCreators({
isLoggedIn:()=>AuthMiddleware.isLoggedIn()
},派遣);
};
导出默认连接(mapStateToProps、mapDispatchToProps)(PrivateRoute);
如果您使用的是react router 4及以上版本,请使用渲染道具和重定向来解决此问题。请参阅:这不是一个安全的解决方案您可以尝试在每个需要登录的页面上使用useEffect钩子: 这将使用“react router dom”中的useHistory钩子
您只需在调用它之前对其进行初始化:
const history = useHistory();
如上所述,这不是一个安全的解决方案,但很简单,我在这里提供了一个类似问题的答案,它可能是有用的。这几乎奏效了。requireAuth调用正确,但是调用replace({pathname:…);挂起我忘记在replace()之后放一个next()。next()函数没有定义,但是您的回答让我走上了正确的轨道模块名是什么?
requireAuth(nextState,
replace)
{
if(!this.authenticated()) // pseudocode - SYNCHRONOUS function (cannot be async without extra callback parameter to this function)
replace('/login');
}
render() {
return (
<Router history={hashHistory}>
<Route path="/" component={AppMain}>
<Route path="login" component={Login}/>
<Route path="logout" component={Logout}/>
<Route path="subject" component={SubjectPanel} onEnter={this.requireAuth}/>
<Route path="all" component={NotesPanel} onEnter={this.requireAuth}/>
</Route>
</Router>
);
}
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Route, Redirect } from 'react-router-dom';
import AuthMiddleware from 'modules/middlewares/AuthMiddleware';
class PrivateRoute extends Component {
static propTypes = {
component: PropTypes.func.isRequired,
isAuthenticated: PropTypes.bool,
isLoggedIn: PropTypes.func.isRequired,
isError: PropTypes.bool.isRequired
};
static defaultProps = {
isAuthenticated: false
};
constructor(props) {
super(props);
if (!props.isAuthenticated) {
setTimeout(() => {
props.isLoggedIn();
}, 5);
}
}
componentWillMount() {
if (this.props.isAuthenticated) {
console.log('authenticated');
} else {
console.log('not authenticated');
}
}
componentWillUnmount() {}
render() {
const { isAuthenticated, component, isError, ...rest } = this.props;
if (isAuthenticated !== null) {
return (
<Route
{...rest}
render={props => (
isAuthenticated ? (
React.createElement(component, props)
) : (
<Redirect
to={{
pathname: isError ? '/login' : '/welcome',
state: { from: props.location }
}}
/>
)
)}
/>
);
} return null;
}
}
const mapStateToProps = (state) => {
return {
isAuthenticated: state.auth.isAuthenticated,
isError: state.auth.isError
};
};
const mapDispatchToProps = (dispatch) => {
return bindActionCreators({
isLoggedIn: () => AuthMiddleware.isLoggedIn()
}, dispatch);
};
export default connect(mapStateToProps, mapDispatchToProps)(PrivateRoute);
useEffect(() => {
const token = localStorage.getItem('token');
if(!token) {
history.push('/login');
}
}
const history = useHistory();