ember-simple-auth or Your Own
The Session Service — Auth State
A session service holds the authenticated user, the token, and helpers like authenticate and invalidate.
What you'll learn
- Use ember-simple-auth or roll your own
- Expose a tracked currentUser
- Persist sessions via a session store
Most apps have a single source of truth for “who is logged in.” In Ember,
that’s a session service — either the popular ember-simple-auth addon or
a small service you write yourself.
Roll Your Own
For straightforward token auth, a custom service is short and clear:
// app/services/session.js
import Service, { service } from '@ember/service';
import { tracked } from '@glimmer/tracking';
export default class SessionService extends Service {
@service store;
@tracked currentUser = null;
@tracked token = localStorage.getItem('token');
get isAuthenticated() {
return Boolean(this.token);
}
async login(email, password) {
const res = await fetch('/api/login', {
method: 'POST',
body: JSON.stringify({ email, password }),
});
const { token, user } = await res.json();
this.token = token;
this.currentUser = user;
localStorage.setItem('token', token);
}
invalidate() {
this.token = null;
this.currentUser = null;
localStorage.removeItem('token');
}
} Use It Everywhere
// app/adapters/application.js
import JSONAPIAdapter from '@ember-data/adapter/json-api';
import { service } from '@ember/service';
export default class ApplicationAdapter extends JSONAPIAdapter {
@service session;
get headers() {
return this.session.token
? { Authorization: `Bearer ${this.session.token}` }
: {};
}
} ember-simple-auth
For more complex flows (OAuth, refresh tokens, multiple session stores), use the addon:
ember install ember-simple-auth It ships with authenticators, session stores (cookie, localStorage, ephemeral),
and route mixins. The newer pattern is to check auth in beforeModel:
import Route from '@ember/routing/route';
import { service } from '@ember/service';
export default class ProtectedRoute extends Route {
@service session;
@service router;
beforeModel() {
if (!this.session.isAuthenticated) {
this.router.transitionTo('login');
}
}
}