Ember SimpleAuth authenticate access to protected resources

好久不见. 提交于 2019-12-11 22:51:10

问题


I have an app where users can edit organisations in various 'pages'.

App.Router.map(function() {
  this.resource('organisation', {path: '/:orgname'}, function () {
    this.route('foo');
    this.route('bar');
  });
});

I want users to be able to view any organisation but the various pages should become editable if the user has admin rights over the organisation.

Organisations are editable based on some tricky logic handled by the server. The user model has an organisations attribute to reflect these admin rights. This is mirrored in the organisation object. On the server its a many-to-many table plus some other logic.

App.User = DS.Model.extend({
  primaryKey: 'username',
  fullname: DS.attr('string'),
  username: DS.attr('string'),
  organisations: DS.hasMany('organisation', {async: true})
});

App.Organisation = DS.Model.extend({
  primaryKey: 'orgname',
  orgname: DS.attr('string'),
  fullname: DS.attr('string', {defaultValue: 'Unnamed Organisation'}),
  description: DS.attr('string'),
  users: DS.hasMany('user', {async: true}),
});

I am using Ember SimpleAuth to authenticate via a login page and to authorise requests to my API. I use a custom session to load in data for the authenticated user.

var CustomSession = SimpleAuth.Session.extend({
  user: function() {
    var username = this.get('username');
    if (!Ember.isEmpty(username)) {
      return this.container.lookup('store:main').find('user', username);
    }
  }.property('username')
});

I have a controller like this which makes attributes editable in my template.

App.OrganisationController = Ember.Controller.extend({
  actions: {
    ToggleEditFullname: function() {
      this.set('editingFullname', !this.get('editingFullname'));
    },
    save: function() {
      this.set('editingFullname', false);
      return true;
    }
  }
});

So in my template I do something like this...

  {{#if editingFullname}}
    {{view Ember.TextField valueBinding="model.fullname" placeholder="Full name"}}
    <a href="#"><i {{action 'ToggleEditFullname'}} class="fa fa-times" title="cancel"></i></a>
  {{else}}
    {{#if model.fullname}}
      {{model.fullname}}
    {{else}}
      No name provided...
    {{/if}}
    {{#if session.isAuthenticated}}
      <a href="#"><i {{action 'ToggleEditFullname'}} class="fa fa-pencil" title="edit name"></i></a>
    {{/if}}
  {{/if}}

The key being the {{#if session.isAuthenticated}} statement. This ensures that users only get access to the restricted features if they are logged in.

All pretty normal so far (I think).

However, I want to be able to ask my session whether the current user is authorised to access the organisation in question. So I'd like to change the {{#if session.isAuthenticated}} to {{#if session.isAuthorised}} and have it check the current model/route against my data.

How can I best do this? Is there a better alternative? How do I protect resources individually?

P.S. Apologies for my English spelling of 'authorized'.


回答1:


You'd want to compute from each organization so that it will be accurate on a per-model basis. So change

{{#if session.isAuthenticated}}

to

{{#if model.userCanAdminister}}

Then you can compute that straight off the model definition (this is probably not suitable for your async case, but could be workable) as seen here: http://emberjs.com/guides/models/defining-models/#toc_defining-attributes

Or you can do it from the itemController (how I would do it for async). The logic for that should be pretty simple. Check if the current user is contained in the organization's user collection. Return a boolean from the computed property. Have that property bound to session.isAuthenticated and then users.@each.content or whatever might change in the organization in real-time.

Hope that helps!



来源:https://stackoverflow.com/questions/25015898/ember-simpleauth-authenticate-access-to-protected-resources

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!