meteor-roles: !Roles.userIsInRole(Meteor.user(), ['admin']) not working as expected in firefox(42.0 for ubuntu).

I am trying to write a onBeforeAction in routing javascript file (name:common.js, it is placed in a folder common to server and client called libs), but the routing does not happen because,

In Firefox: !Roles.userIsInRole(Meteor.user(), ['admin']) returns true (unexpected) during execution in javascript (common.js), which I know because I used alert(), and if I execute !Roles.userIsInRole(Meteor.user(), ['admin']) in browser console itself, then it returns false (expected). I even tried moving common.js to client side, the issue still prevails.

In Chrome: I know this is a issue because, it executes perfectly in Chrome, and returns false in browser console and common.js (as expected, in any case, even if common.js is on clientside or in common folder).

Just in case it helps (code):

Router.route('/rolesadmin', {
        template: 'adminTemplate',
        onBeforeAction: function() {
            alert(!Roles.userIsInRole(Meteor.user(), ['admin']));
            if (Meteor.loggingIn()) {
                this.render(this.loadingTemplate);
            } else if(!Roles.userIsInRole(Meteor.user(), ['admin'])) {
                this.redirect('/');
            }
            else{
                this.next();
            }
        }
    });

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 15 (6 by maintainers)

Most upvoted comments

@adammoisa Careful with this, it is not recommended. You should definitely not be doing roles checking in routing. Rather, its best to move the checks into the templates themselves.

Display the requested template as soon as possible, but with a loading message. Once subs are loaded, if action needs to be taken, redirect from template. See my vid on FlowRouter Auth, linked above.

For a bit of background, one of the main reasons why Arunoda wrote FlowRouter when IronRouter already existed was to cut out these kind of performance issues. IronRouter’s design encouraged a lot of logic to take place before anything was shown to the client. You didn’t have to do it that way but most people did and it resulted in poor perceived performance. With FlowRouter, he purposefully made it non-reactive so that it would be hard to shoot yourself in the foot that way.

You’re “loading…” message is displayed whenever the user is not admin so that logic is incorrect. Rather you should display “loading” while you are waiting for the roles subscription to complete. The handle is stored here: Roles.subscription.

As for the checksum, I don’t know React or SSR so I’m afraid I can’t be much help there. I’d suggest making as minimal an app as you can and then add back pieces until you trigger the error. Then you’ll know what it is that is causing it and can debug from there.

This sounds like a race condition between when the check is executing and when the data is available on the client.

I did a talk covering this at a recent DevShop NY; you can see a description of the sequence of events in my slides here: http://slides.com/alanning55/a-pattern-for-flowrouter-auth/#/4

The only weird thing is that I thought onBeforeAction was reactive so I would expect the check to return false until the data got there but then return true once the route re-runs.

The best way to avoid these kinds of race conditions is to move the auth checks to your templates. You can find examples of how to do this in these examples in this repo: