Ember Simple Auth – How to Access the Current User in the Model Hook

Almost any serios web and mobile app has to deal with authentication at some point. Being a security matter this is not always easy to get done. Luckily, in Ember.js there is a great add-on for this. Ember Simple Auth is the standard solution for authorisation and authentication in Ember.

Apart from standard authorisation and authentication you can also extend this ESA’s functionality. For example have a current user property that you can use throughout your app.

Let’s assume that you need to access the current user in your route. You’ll likely need this so that you can retrieve a record or query your backend for some data based on it.

Make the current user available in your application via a service and inject it in your route. Here’s how you can do that, following the Ember Simple Auth documentation. There are 2 ways to request the current user:

Using a dedicated end point

// app/services/current-user.js
import Ember from 'ember';

const { inject: { service }, RSVP } = Ember;

export default Ember.Service.extend({
  session: service(),
  store: service(),

  load() {
    if (this.get('session.isAuthenticated')) {
      return this.get('store').queryRecord('user', { me: true }).then((user) => {
        this.set('user', user);
      });
    } else {
      return RSVP.resolve();
    }
  }
});

// app/adapters/user.js
import ApplicationAdapter from './application';

export default ApplicationAdapter.extend({
  urlForQueryRecord(query) {
    if (query.me) {
      delete query.me;
      return `${this._super(...arguments)}/me`;
    }

    return this._super(...arguments);
  }
});

Loading the user with its id

// app/services/current-user.js
import Ember from 'ember';

const { inject: { service }, isEmpty, RSVP } = Ember;

export default Ember.Service.extend({
  session: service(),
  store: service(),

  load() {
    let userId = this.get('session.data.authenticated.user_id');
    if (!isEmpty(userId)) {
      return this.get('store').findRecord('user', userId).then((user) => {
        this.set('user', user);
      });
    } else {
      return RSVP.resolve();
    }
  }
});

You now need to load the current user and populate the currentUser service user property. To do that you need to call the currentUser service load method.

// app/routes/application.js
import Ember from 'ember';
import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin';

const { service } = Ember.inject;

export default Ember.Route.extend(ApplicationRouteMixin, {
  currentUser: service(),

  beforeModel() {
    return this._loadCurrentUser();
  },

  sessionAuthenticated() {
    this._super(...arguments);
    this._loadCurrentUser();
  },

  _loadCurrentUser() {
    return this.get('currentUser').load().catch(() => this.get('session').invalidate());
  }
});

The current user in action

And now you have access to the current user via the currentUser service you created. Here’s an example of how you could use this. Given you have a list of bookings available at /bookings, you need a way to display all the bookings that belong to the current user at /bookings/me. Easy enough. Here’s how you can do this:

// app/routes/bookings/me.js
import Ember from 'ember';

const { inject: { service } } = Ember;

export default Ember.Route.extend({
  currentUser: service(),
   
  model() {
    let userId = this.get('currentUser.user.id');
    return this.store.query('booking', { user_id: userId });
  }
});

There are many use cases and needs for the current user and it’s not always this simple to solve your problem. But at least this gives you a starting point if you need to get more creative.