Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to restrict a route to an admin user in Meteor?

Tags:

meteor

as an iOS developer primarily, I'm very new to webdev. I'm looking into Meteor and have some questions regarding routing -- my apologies if they are very easy.

I am using the Meteor Router package to create routes, but I would like to have some pages only accessible to the admin user.

  Meteor.Router.add({
        '/'         : 'home',
        '/admin'    : 'admin'
    });

So I have a simple route setup as above, but I'm not sure how to restrict access to the /admin route.

Is it as simple as something like this? What would be a good way to restrict the route to the /admin page and show a warning or perhaps even redirect them back to the / page?

Thank you!

client.html

<head>
   <title>My App</title>
</head>

<body>
   {{renderPage}}
</body>

<template name="home">
    {{greeting}}
</template>

<template name="admin">
    {{greeting}}
</template>

client.js

Template.admin.greeting = function () {
   var currentUser = Meteor.user();
   if (null !== currentUser && 'admin' === currentUser.username) {
       return "Hello Admin!";
   }
   else{
      return "Sorry, only admins can see this page";
   }
};
like image 903
kurisukun Avatar asked Jun 11 '13 02:06

kurisukun


3 Answers

The best way to restrict access to a route is with the router itself (rather than pushing the problem to your controller). You have a couple of choices in how you do this:

Routing Function

You could make the /admin route look like:

'/admin': function() {
  return {
    as: 'admin',
    to: function() {
      if (Meteor.user() && Meteor.user().username === 'admin') {
        return 'admin';
      } else {
        return 'unauthorized';
      }
    }
  };
}

I'm assuming you have an unauthorized template that renders a 403 page or something informative.

Filter

Alternatively, you can leave your original /admin route as it was and add a filter:

Meteor.Router.filters({
  'needsAdmin': function(page) {
    if (Meteor.user() && Meteor.user().username === 'admin') {
      return page;
    } else {
      return 'unauthorized';
    }
  }
});

and use it like so:

Meteor.Router.filter('needsAdmin', {only: 'admin'});

Personally, I like the filter option because it's reusable and it's a little more obvious what's going on.

like image 156
David Weldon Avatar answered Oct 23 '22 11:10

David Weldon


Another solution is to use Roles package and make sure the user has the 'admin' role before serving data.

$ mrt add roles

Then you can check for roles like with a nice syntax:

if(!Roles.userIsInRole(Meteor.user(), ['admin'])) {
    // Redirect...
}

Roles is integrated with the Meteor accounts system and plays nicely with most of the accounts packages.

If you are looking to manage accounts (create/delete Roles and add/remove Roles from a given user) I've created the package Accounts Admin UI. The README has a quickstart and some some notes on how to integrate this with other routing packages.

$ mrt add accounts-admin-ui-bootstrap-3
like image 25
hharnisc Avatar answered Oct 23 '22 11:10

hharnisc


Use the and parameter:

Meteor.Router.add({
  '/admin': { to: 'admin', and: function() {
    if (!Meteor.user() || Meteor.user().name != 'admin'){
      Meteor.Router.to('/');
    }
  }}
});
like image 37
gabrielhpugliese Avatar answered Oct 23 '22 11:10

gabrielhpugliese