Security with templates and with Iron Router redirects

I’m enjoying working with Meteor and trying out new things, but I often try to keep security in mind. So while I’m building out a prototype app, I’m trying to find the best practices for keeping the app secure. One thing I keep coming across is restricting a user based on either a roll, or whether or not they’re logged in. Here are two examples of issues I’m having.

// First example, trying to only fire an event if the user is an admin
// This is using the alaning:roles package{
  "click .someclass": function(event) {
    if (Roles.userIsInRole(Meteor.user(), 'admin', 'admin-group') {
      // Do something only if an admin in admin-group

My problem with the above is I can override this by typing:
Roles.userIsInRole = function() { return true; } in this console. Ouch.

The second example is using Iron Router. Here I want to allow a user to the “/chat” route only if they’re logged in.

Router.route("/chat", {
  name: 'chatHome',
  onBeforeAction: function() {
    // Not secure! Meteor.user = function() { return true; } in the console.
    if (!Meteor.user()) {
      return this.redirect('homeIndex');
    } else {;
 waitOn: function () {
    if (!!Meteor.user()) {
      return Meteor.subscribe("messages");
 data: function () {
   return {
      chatActive: true

Again I run into the same problem. Meteor.user = function() { return true; } in this console blows this pattern up. The only way around this I have found thus far is using a Meteor.method call, which seems improper, as they are stubs that require callbacks.

What is the proper way to address this issue?


Using a callback doesn’t work for me since it’s calling for a response asynchronously. It’s moving out of the hook before it can handle the response.

onBeforeAction: function() {
  var self = this;'someBooleanFunc', function(err, res) {
    if (!res) {
      return self.redirect('homeIndex');
    } else {;

I’ve also posted this question on Stack Overflow if you’re interested in answering it in both places.

These are valid concerns. It is important to realize that client side security exists solely for optimistic UI behavior. It is not where your security exists.

The security should be in your server side methods and publications. These should know what data requires a logged in user, and what requires roles.

For security conscious areas, the templates themselves need to be aware of the calls and subscriptions and be able to trigger a redirect. They also shouldn’t even try to render until the data is ready, instead showing either a loading indicator or simply nothing (if the data shows up fast enough). Again, client security isn’t actual security, it is just an optimistic UI.

Interesting point @lassombra . I definitely do realize the need for the pub/sub model and for it to know who to share data with. What do you mean by the templates themselves need to be aware of the calls and able to trigger a redirect? Do you mean within a template helper or within the html of the template? I can’t see a way to do a template redirect without a sophisticated client being able to override the functionality to do so. Other than what I’ve shown, would you be able to give a small example of a more secure redirect?

If you move your subscriptions into the template (which is the current best practice) then when the subscription fails in the template you can do Router.go(/* whatever here */).

The best place to put this logic for templates is Template.onCreated.

Also, as you are just getting started, I would switch over to Flow Router. Iron Router is not well maintained anymore and flow router just does things better. The only thing Iron Router does is route level subscriptions, but that has been widely accepted to be an overly opinionated way to do subscriptions.

Iron router was a good start for meteor, but flow router came along and showed the world how it could be done better.

Fantastic, thanks for the insight! Very helpful. I will go check out Flow Router now; I have been seeing it a lot lately in Q&As.