J
J
jspie2017-04-05 21:16:24
Express.js
jspie, 2017-04-05 21:16:24

How to implement a competent authorization check?

There are three components: SignIn, Home , Account t. After successful authorization in the SignIn component , the user data is available in the Redux store. How to organize a competent redirection in the following cases:
If the user entered the Account page without authorization, he will be redirected to SignIn and vice versa, in case of authorization, when going to SignIn , he will be redirected to Home .
The server creates a session and it stores user data.
How to work with all this? Are there any examples? Tell.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
M
Maxim, 2017-04-05
@jspie

Are you using react-router? If so, then everything is simple:
1) routes are created using a function, so you can throw store into the routing

...
import configRoutes from '../../routes'
...
render() {
  return (
    <Provider store={store}>
      <Router history={routerHistory}>
        {configRoutes(store)}
      </Router>
    </Provider>
  )
}

2) Further in the routing, set the onEnter hook on the "protected" components:
...
<Route path='/secret-area' component={SecretAreaContainer} onEnter={_ensureAuthenticated}>
...

3) the function itself, checks if the store has the necessary data:
export default function configRoutes(store) {
  function _ensureAuthenticated(nextState, replace, callback) {
    const { dispatch } = store
    const { session } = store.getState()
    const { currentUser } = session // данные по юзеру
    let nextUrl

    if (!currentUser && localStorage.getItem('token')) {
        dispatch(getCurrentAccount())
      }
    } else if (!localStorage.getItem('token')) {
      nextUrl = location.pathname + location.search.replace('?', '&')
      replace('/signin')
    }

    callback()
  }

  // здесь ваши роуты

Ok, the routes are ready.
Now, by redirection:
export function signIn(email, password) {
  return (dispatch, getState) => {

    dispatch({
      type: USER_SIGN_IN_REQUEST,
    })

    const params = {
      email,
      password,
    }

    httpPost(`${API_ROOT_V1}/api/authenticate`, params)
      .then((data) => {
        saveParamsToLS(data) // здесь токен можно сохранить, например
        dispatch(push('/account')) // ваш РЕДИРЕКТ, используется push из react-router-redux (что необязательно)
      })
      .catch((error) => {
        console.warn(`Sign in error: ${JSON.stringify(error)}`) //eslint-disable-line no-console
        dispatch({
          type: USER_SIGN_IN_FAILURE,
          error: error,
        })
      })
  }
}

and the case with direct entry remains: you must resolve this again in the onEnter hook in the router. Since you have a store, and all the data from it is available to you, including the store.dispatch method, it will not be difficult to finish the example.

D
davidnum95, 2017-04-06
@davidnum95

You can use HOC for this. Sample implementation:

export default function(ComposedComponent) {
  class Authenticate extends React.Component {

    componentWillMount() {
      if (!localStorage.jwtToken) {
        this.context.router.push('/auth');
      }

    }

    componentWillUpdate(nextProps, nextState) {
      if (!nextProps.isAuthenticated) {
        this.context.router.push('/auth');
      }
    }

    render() {
      return (
        <ComposedComponent {...this.props} />
      );
    }
  }

  Authenticate.propTypes = {
    isAuthenticated: React.PropTypes.bool.isRequired,
  };

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

  function mapStateToProps(state) {
    return {
      isAuthenticated: state.auth.isAuthenticated,
    };
  };

  return connect(mapStateToProps, { })(Authenticate);

}

In the router:
<Route path="/main" component={requireAuth(MainPage)} />

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question