9

Tôi viết một Phản ứng .js ứng dụng (v15.3) sử dụng phản ứng-router (v2.8.1) và ES6 cú pháp. Tôi không thể lấy mã bộ định tuyến để chặn tất cả các chuyển tiếp giữa các trang để kiểm tra xem người dùng có cần phải đăng nhập trước không.Kiểm tra nếu Logged in - Phản ứng Router App ES6

cấp cao nhất của tôi làm cho phương pháp này rất đơn giản (các ứng dụng là tầm thường cũng):

render() 
    { 
     return (
     <Router history={hashHistory}> 
      <Route path="/" component={AppMain}> 
       <Route path="login" component={Login}/> 
       <Route path="logout" component={Logout}/> 
       <Route path="subject" component={SubjectPanel}/> 
       <Route path="all" component={NotesPanel}/> 
      </Route> 
     </Router> 
    ); 
    } 

Tất cả các mẫu trên mã web sử dụng ES5 hoặc phiên bản cũ của phản ứng-router (lớn hơn phiên bản 2) , và những nỗ lực khác nhau của tôi với mixins (không được chấp nhận) và willTransitionTo (không bao giờ được gọi) đã thất bại.

Làm cách nào để tôi có thể thiết lập 'chức năng chặn đánh chặn' toàn cầu để buộc người dùng xác thực trước khi truy cập trang họ yêu cầu?

+0

Tôi đã cung cấp câu trả lời cho một câu hỏi tương tự ở đây, nó có thể hữu ích. http://stackoverflow.com/a/39098876/6060774 – alexi2

Trả lời

1

Phiên bản này của callback OnEnter cuối cùng làm việc cho phản ứng-router (V2.8):

requireAuth(nextState, 
       replace) 
    { 
     if(!this.authenticated()) // pseudocode - SYNCHRONOUS function (cannot be async without extra callback parameter to this function) 
     replace('/login') 
    } 

Các liên kết này giải thích phản ứng-router khác biệt chuyển hướng giữa V1 vs v2 là here. phần có liên quan được trích dẫn dưới đây:

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' } }) 

Full Mã Dưới (phản ứng-router phiên bản 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> 
); 
} 
6

Mọi tuyến đường đều có móc nối onEnter được gọi trước khi quá trình chuyển tuyến xảy ra. Xử lý hook onEnter với hàm requireAuth tùy chỉnh.

<Route path="/search" component={Search} onEnter={requireAuth} /> 

Yêu cầu mẫuAuthêm được hiển thị bên dưới. Nếu người dùng được xác thực, chuyển đổi qua next(). Khác thay thế tên đường dẫn bằng/đăng nhập và chuyển đổi qua next(). Thông tin đăng nhập cũng được chuyển vào tên đường dẫn hiện tại để sau khi đăng nhập hoàn tất, người dùng được chuyển hướng đến đường dẫn ban đầu được yêu cầu.

function requireAuth(nextState, replace, next) { 
    if (!authenticated) { 
    replace({ 
     pathname: "/login", 
     state: {nextPathname: nextState.location.pathname} 
    }); 
    } 
    next(); 
} 
+0

Điều này gần như hoạt động. requireAuth được gọi đúng nhưng gọi để thay thế ({pathname: ...); treo – DataMania

+0

Tôi quên đặt một() sau thay thế(). – vijayst

+0

Hàm next() không được xác định, nhưng câu trả lời của bạn đặt tôi vào đúng hướng – DataMania

1

Trong v4 bạn chỉ cần tạo một thành phần tuyến đường để kiểm tra nếu sử dụng được xác thực và trả về các thành phần tiếp theo và tất nhiên thành phần tiếp theo có thể là các tuyến khác.

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); 
Các vấn đề liên quan