简体   繁体   中英

Making Meteor method calls synchronous on the client

I feel like I'm missing something. I was trying to tailor my product UI so that certain items are only displayed for admins. In addition, restricting access to certain "pages" in the router requires a synchronous call guard. I'd certainly prefer to keep things asynchronous, but that doesn't seem to meet the requirements.

In other environments, I'd create a boolean function like isAdmin() that checks user authorization/roles. But since users shouldn't see the implementation of the function for security reasons, it's best to use a server-only Meteor method. Although the method could be synchronous on the client (if no callback specified), the only way to get the return value is to use the asynchronous callback form of Meteor.call().

It seems like there are three ways to handle this, none of which are as simple as the boolean function:

  1. Return an Observable from isAdmin(), but this pushes the issue out to wherever isAdmin() is called. It doesn't solve the router guard issue.
  2. Do a Meteor.call() wherever isAdmin() is needed, discarding the isAdmin() function. This also pushes the problem to all the call sites, and doesn't address the router guard.
  3. Don't return a value at all, but have the server-side method throw an exception if the user is not an admin. This, however, doesn't change the asynchronous nature of the method call.

I've seen examples using Meteor.wrapAsync or Future, but these use Fibers on the server, not the client.

Any other suggestions for other patterns, perhaps using rxjs? Thanks.

i think i'm not understanding your overall security strategy, but here are a couple things to think about.

security happens on the server, which it looks like you're well aware of.

in my current project, we use roles ( alanning:roles ), and have several admin roles. these roles are published with the Meteor.user object, so on the client we can enable/disable links to pages by checking that.

so we agree that doing so isn't real security, because a user can simply navigate to that link or change their client Meteor.user object to expose that.

but on that page, we're probably going to be accessing admin-only data. since we handle the publish on the server, where we can check those admin roles for real, we can detect a non-admin user access and throw an error.

similarly, if we're publishing data to a user, and the items they get are based on roles, we can check that in the publish and publish only those items they're allowed to see. same idea with restricting fields on those published items.

to your question about "what does that client code look like that checks the roles?", it's really doing nothing more than querying the contents of the "roles" field on Meteor.user. so while it does give them a hint of what roles exist and how the app users them for visibility, imho it doesn't provide a path for mischief. so long as they can't access any restricted data, or successfully execute any restricted calls, it's secure.

so for each of our publishers and Meteor methods, we have tons of error checking, including roles (admin and otherwise). if anything doesn't line up, we throw an error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM