Closed sahanDissanayake closed 8 years ago
I'm having a similar issue, it seems? When the server does a hot reload a check fails on a page, but if I manually visit it the check succeeds. It's the exact same query (I've checked), but it returns no results in one case and returns the correct result in another? Could it have something to do with the state of the database while a hot code reload is happening?
I can't think of a case where client-side would give a positive result but server-side would fail. Usually its the opposite due to the time it takes for data to get to the client.
What are the contents of the user record's roles
field in the database?
Can you post a reproduction somewhere for me to dig in further?
I’m new to Meteor, but I will try to produce a reproduction for you. Thanks!
On Dec 13, 2015, at 9:23 PM, Adrian Lanning notifications@github.com wrote:
I can't think of a case where client-side would give a positive result but server-side would fail. Usually its the opposite due to the time it takes for data to get to the client.
What are the contents of the user record's roles field in the database?
Can you post a reproduction somewhere for me to dig in further?
— Reply to this email directly or view it on GitHub https://github.com/alanning/meteor-roles/issues/154#issuecomment-164237389.
Is this the wrong way to go about redirecting users who try to access an invalid route with Iron Router? Perhaps this is the source of my problem?
Router.route("/private", {
onBeforeAction: function() {
if (!Roles.userIsInRole(Meteor.userId(), "admin")) {
Router.go("/public");
} else {
this.next();
}
},
action: function () {
this.render("private");
}
});
I think that should work if onBeforeAction
is reactive but I haven't used that specific syntax before. You can check out how I did it in this iron-router example:
https://github.com/alanning/meteor-roles/blob/master/examples/iron-router/client/routing.js
Better yet, you can avoid doing it in the routes entirely if you implement it like this example:
https://github.com/alanning/meteor-roles/tree/master/examples/flow-router-advanced
The neat thing about this pattern is that you can do it the same way whether you use IronRouter or FlowRouter. It should make your app a lot easier to work with and refactor.
I think in my case it's some kind of race condition issue between client and server. It's funny: I was able to recreate it last night but not this morning. Then I added a delay function in the routing to the server and now it seems to display the odd behaviour again. I'll paste code below for you to try. What happens is that you're effectively unable to access the the "private" page. You get redirected to the public page even if you're supposed to have access. Try going to /private even when logged in as the admin user and it doesn't work.
My best guess is that the client attempts to process the routing first, but since the roles aren't published it redirects itself back to the public page. The server (assuming it runs later, which is why I added the manual delay) somehow doesn't redirect the client back to the private page even though it should have access. Does that make sense? Does it sound like what's happening?
repro.html
<body>
{{> loginButtons}}
</body>
public.html
<template name="public">
You're on a public page
</template>
private.html
<template name="private">
You're on a private page
</template>
repro.js
if (Meteor.isServer) {
if (Meteor.users.find().count() <= 0) {
Accounts.createUser({
username: "nonadmin",
email: "email@address.com",
password: "password"
});
var adminId = Accounts.createUser({
username: "admin",
email: "important@critical.com",
password: "verysecret"
});
Roles.addUsersToRoles(adminId, "admin");
}
}
Router.route("/public", function() {
this.render("public");
});
Router.route("/private", {
onBeforeAction: function() {
// wait
if (Meteor.isServer) {
var Future = Npm.require('fibers/future');
var future = new Future();
Meteor.setTimeout(function() {
future.return();
}, 1000);
future.wait();
}
if (!Roles.userIsInRole(Meteor.userId(), "admin")) {
Router.go("/public");
} else {
this.next();
}
},
action: function () {
this.render("private");
}
});
@aardvarkk Yes, it sounds like a race condition, not sure why its not re-running for you.
This is not the same thing as what @sahanDissanayake was reporting. Please see my reply to your other posting which includes links to a presentation explaining what is happening and examples of how to avoid it: https://github.com/alanning/meteor-roles/issues/152#issuecomment-164235804
@sahanDissanayake I'm closing this issue for now but feel free to reopen if you can post a public repro or more info on the scenario you were seeing.
To follow up on this, my talk on FlowRouter Auth is now up on the Meteor YouTube channel: https://www.youtube.com/watch?v=KK_ua6vxkP4
Hi @alanning
I'm using this on react ssr
I do this check Roles.userIsInRole(Meteor.user(), 'admin')
This returns true on clientside but false on server side.. Any thoughts ?