Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restrict Access (Meteor + React Router + Roles)

I am trying to implement alanning Meteor-roles with react-router in my Meteor application. Everything is working fine except the fact I can't manage properly to restrict a route using alanning roles or Meteor.user()

I tried with meteor-roles:

I am trying to use the onEnter={requireVerified} on my route. This is the code:

const requireVerified = (nextState, replace) => {
    if (!Roles.userIsInRole(Meteor.userId(), ['verified'],'user_default')) {
        replace({
            pathname: '/account/verify',
            state: { nextPathname: nextState.location.pathname },
        });
    }
};

I tried with Meteor.user():

const requireVerified = (nextState, replace) => {
  if (!Meteor.user().isverified == true) {
    replace({
      pathname: '/account/verify',
      state: { nextPathname: nextState.location.pathname },
    });
  }
};

So this is working when I am clicking on a route link, but when i manually refresh (F5), it does not work. After digging into it, i have found that Meteor.user() is not ready when i manually refresh the page.

I know Meteor.userid() or Meteor.logginIn() are working, but i wanted to verify not just that they are logged but if they are "verified" or have a role.

I also tried to check inside the component with react, with componentDidMount() or componentWillMount(), in both cases it's the same, the manual fresh does not load Meteor.user() before the compenent is mounted.

So what is the best way to restrict components/routes with meteor/alaning roles + react router ? (I am using react-komposer inside TheMeteorChef's base)

Thank you.

like image 808
NOaMTL Avatar asked Aug 26 '16 14:08

NOaMTL


People also ask

How do you navigate in react dom on a router?

There are two ways to programmatically navigate with React Router - <Navigate /> and navigate() . You can get access to Navigate by importing it from the react-router-dom package and you can get access to navigate by using the custom useNavigate Hook.

How do I restrict access to my router in react?

To restrict access to routes in React Router, we set the render prop to a function that renders the component we want according to the condition we're checking. import { Route, Redirect } from "react-router"; <Route exact path="/" render={() => (loggedIn ?

How do you handle role based routing and role based component in react?

Define Roles and Permissions at the backend. After login (authentication), control the routes based on permissions (authorization). Create a component like Check which would check if current user is having enough permissions to see this page or not. Google for keywords "authorization" in general and in react app.


1 Answers

Note I have not tried it yet, it's only a suggestion

One thing you could try is to use componentWillReceiveProps alongside createContainer from 'react-meteor-data' like that:

import React, { Component, PropTypes } from 'react';
import { Meteor } from 'meteor/meteor';
import { createContainer } from 'meteor/react-meteor-data';
import { Roles } from 'meteor/alanning:roles';

class MyComponent extends Component {
  componentWillReceiveProps(nextProps) {
    const { user } = nextProps;
    if (user && !Roles.userIsInRole(user._id, ['verified'], 'user_default')) {
      browserHistory.push('/account/verify');
    }
    // If Meteor.user() is not ready, this will be skipped.
  }
}

MyComponent.propTypes = {
  user: PropTypes.object,
};

export default createContainer(() => {
  const user = Meteor.user() || null;
  return { user };
}, MyComponent);

To explain the flow, when the page is loaded, as you said Meteor.user() is not defined so you can't check the permissions. However, when Meteor.user() gets defined, this will trigger a refresh of the template, and the new props will be passed to componentWillReceiveProps. At this moment you can check if user has been defined and redirect if needed.

To be really sure not to miss anything, I would actually put the verification in the constructor() as well (defining a function that takes the props as arguments and calling it in both constructor() and componentWillReceiveProps()).

like image 129
Max G. Avatar answered Oct 20 '22 14:10

Max G.