Mi sitio web tiene algunas páginas protegidas por inicio de sesión. Mi solución actual para esto es:

En app.js:

<div className="app">
        <Provider store={store}>
            <Router history={appHistory} onUpdate={fireTracking}>
                <Route name="main" component={AppHandler}>
                    <Route name="home" path="/" component={HomePageHandler}/>
                </Route>
            </Router>
        </Provider>
    </div>

Y luego mi HomePageHandler es:

export default class HomePageHandler extends BaseAuthorizedComponent {  
    render() {
        return (
            <div>hello</div>
        )
    }
}

A medida que HomePageHandler extiende BaseAuthorizedComponent, que se define como:

class BaseAuthorizedComponent extends Component {

    componentWillMount() {
        if (!this.props.user.signed_in) {
            this.context.router.push('/signin')
        }
    }
}

HomePageHandler.contextTypes = {
    router: React.PropTypes.object.isRequired,
}

function select(state) {
    return {
        user: state.user,
    }
}
export default connect(select)(BaseAuthorizedComponent)

El objeto de usuario de redux tiene un indicador que indica si el usuario ha iniciado sesión o no. La idea es que en la página de inicio, antes de montar el componente, BaseAuthorizedComponent hubiera verificado y redirigido a la página de inicio de sesión si el usuario no está conectado. Mi idea es dejar que cada página que requiera autorización para extender BaseAuthorizedComponent.

Sin embargo, el siguiente error ocurre al intentar cargar la página de inicio:

Error: Could not find "store" in either the context or props of "Connect(BaseAuthorizedComponent)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(BaseAuthorizedComponent)".

No tengo idea de cómo puedo solucionar el problema manteniendo la ventaja de un solo lugar para verificar la autorización. ¿Alguna idea? ¡Gracias!

0
jamesdeath123 24 feb. 2018 a las 23:46

4 respuestas

La mejor respuesta

Después de un poco de investigación, la mejor manera que he visto es esta:

<Route name="name" 
path="/path" 
component={THeWorkHandler} 
onEnter={requireAuth}/>

Y requireAuth se coloca en un archivo auxiliar:

export function requireAuth(nextState, replace) {
    if (!(//logic to see if user is logged in )) {
        replace({pathname: '/user/signin'});
    }
}

De esta manera, si onEnter requireAuth determina que el usuario no está autenticado, redirigirá a la página / user / signin.

0
jamesdeath123 29 may. 2018 a las 19:25

¿Qué tal esto:

class CheckAuth extends React.Component{
   state = {
      auth: false
   }
   render(){
      return(
         {this.state.auth ? <div>Authorized user</div> : <div>Unauthorized user</div>}
      )
   }
}

function mapStateToProps(state){
    return{
      auth: state.auth
    }
}

export default connect(mapStateToProps)(CheckAuth);

Y luego inclúyalo en sus otros componentes así:

import CheckAuth from './CheckAuth';
...
class Home extends React.Component{
   render(){
      return(
        <div>
           <CheckAuth />
           Hello world!!
        </div>
      )
   }
}

export default Home;
0
Singh 24 feb. 2018 a las 22:44

Después de más investigación, la forma más fácil de satisfacer mi requerimiento es:

En un archivo util:

export function requireAuth(nextState, replace) {
    // use your own method to check if user is logged in or not
    if (!isLoggedIn()) {
        replace({pathname: '/signin'});
    }
}

Y luego importe este método en el archivo app.js y úselo:

<div className="app">
        <Provider store={store}>
            <Router history={appHistory} onUpdate={fireTracking}>
                <Route name="main" component={AppHandler}>
                    <Route name="home" path="/" component={HomePageHandler} onEnter={requireAuth}/>
                </Route>
            </Router>
        </Provider>
    </div>

De esta manera, si el usuario requiere autenticación (isLoggedIn () es falso), redirigirá la página a / signin.

0
jamesdeath123 26 feb. 2018 a las 03:33

En primer lugar, es mejor usar composición en lugar de herencia https://reactjs.org/ docs / composition-vs-herencia.html

A continuación, puede agregar el creador de acciones "push" desde react-router-redux (https: // github .com / reactjs / react-router-redux) a la función mapDispatchToProps:

function composeAuth = (ComposedComponent) => {
    class BaseAuthorizedComponent extends React.Component {
        // We use componentDidMount instead of componentWillMount, cause componentWillMount is deprecated https://medium.com/@baphemot/whats-new-in-react-16-3-d2c9b7b6193b
        componentDidMount() {
            if (!this.props.user.signed_in) {
                this.props.push('/signin');
            }
        }
        
        render() {
            if (!this.props.user.signed_in) {
               return null;
            }
            
            return <ComposedComponent {...this.props} />
        }
    }
    
    return connect(state => ({user: state.user}), {push})(BaseAuthorizedComponent);
}

class HomePageHandler extends React.Component {  
    render() {
        return (
            <div>hello</div>
        )
    }
}

export default composeAuth(HomePageHandler);
1
Nik 24 feb. 2018 a las 21:29