{"id":13804875,"url":"https://github.com/mainmatter/ember-simple-auth","last_synced_at":"2025-12-17T03:48:48.551Z","repository":{"id":10413434,"uuid":"12570984","full_name":"mainmatter/ember-simple-auth","owner":"mainmatter","description":"A library for implementing authentication/authorization in Ember.js applications.","archived":false,"fork":false,"pushed_at":"2025-12-04T11:10:27.000Z","size":18928,"stargazers_count":1912,"open_issues_count":42,"forks_count":598,"subscribers_count":32,"default_branch":"master","last_synced_at":"2025-12-06T08:39:21.352Z","etag":null,"topics":["auth","ember","session-management"],"latest_commit_sha":null,"homepage":"https://ember-simple-auth.com","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mainmatter.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2013-09-03T18:03:26.000Z","updated_at":"2025-12-04T11:08:48.000Z","dependencies_parsed_at":"2025-12-15T10:05:00.435Z","dependency_job_id":null,"html_url":"https://github.com/mainmatter/ember-simple-auth","commit_stats":{"total_commits":3269,"total_committers":258,"mean_commits":"12.670542635658915","dds":0.6032425818293057,"last_synced_commit":"accc52e2e146b4055418be2ab57a428220d0dd65"},"previous_names":["simplabs/ember-simple-auth"],"tags_count":100,"template":false,"template_full_name":null,"purl":"pkg:github/mainmatter/ember-simple-auth","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mainmatter%2Fember-simple-auth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mainmatter%2Fember-simple-auth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mainmatter%2Fember-simple-auth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mainmatter%2Fember-simple-auth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mainmatter","download_url":"https://codeload.github.com/mainmatter/ember-simple-auth/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mainmatter%2Fember-simple-auth/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27776592,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-17T02:00:08.291Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["auth","ember","session-management"],"created_at":"2024-08-04T01:00:54.885Z","updated_at":"2025-12-17T03:48:48.535Z","avatar_url":"https://github.com/mainmatter.png","language":"JavaScript","readme":"__[Ember Simple Auth API docs](http://ember-simple-auth.com/api/)__\n\n![CI](https://github.com/mainmatter/ember-simple-auth/workflows/CI/badge.svg)\n\n__[![Discord](https://img.shields.io/discord/480462759797063690.svg?logo=discord)](https://discord.gg/zT3asNS)__\n\n- Ember Simple Auth __supports all Ember.js versions starting with 3.28.__\n- __Doesn't support IE11__\n- Node __\u003e=16 is required__  \n- Supports __Embroider__ see our [ember-try scenario](https://github.com/mainmatter/ember-simple-auth/blob/master/packages/test-esa/config/ember-try.js) and [test app](https://github.com/mainmatter/ember-simple-auth/blob/master/packages/test-app/ember-cli-build.js) for guidance.\n\n\u003e [!NOTE]\n\u003e Ember Simple Auth was written and is maintained by [Mainmatter](https://mainmatter.com) and contributors.\n\u003e We offer consulting, training, and team augmentation for Ember.js – check out our [website](https://mainmatter.com/ember-consulting/) to learn more!\n\n# Ember Simple Auth\n\n![Logo](http://ember-simple-auth.com/images/logo.png)\n\nEmber Simple Auth is a __lightweight library for implementing authentication/\nauthorization with [Ember.js](http://emberjs.com) applications__. It has\nminimal requirements with respect to application structure, routes etc. With\nits pluggable strategies it __can support all kinds of authentication and\nauthorization mechanisms__.\n\n# Table of Contents\n\n**Basic Information**\n\n* [What does it do?](#what-does-it-do)\n* [How does it work?](#how-does-it-work)\n* [Example App](#example-app)\n\n**Usage**\n\n* [Installation](#installation)\n* [Walkthrough](#walkthrough)\n\n**Core Feature Guides**\n\n* [The Session Service](#the-session-service)\n* [Authenticators](#authenticators)\n  * [Customizing an Authenticator](#customizing-an-authenticator)\n  * [Implementing a custom Authenticator](#implementing-a-custom-authenticator)\n* [Session Stores](#session-stores)\n  * [Store Types](#store-types)\n  * [Implementing a Custom Store](#implementing-a-custom-store)\n* [FastBoot](#fastboot)\n* [Engines](#engines)\n* [Testing](#testing)\n\n**Other Guides**\n\n* [Managing a current User](guides/managing-current-user.md)\n* [GitHub authorization with torii](guides/auth-torii-with-github.md)\n* [Upgrading to v7](guides/upgrade-to-v7.md)\n* [Upgrading to v4](guides/upgrade-to-v4.md)\n* [Upgrading to v3](guides/upgrade-to-v3.md)\n\n**Other Resources**\n\n* [Upgrading from Pre-1.0 versions](https://mainmatter.com/blog/2015/11/27/updating-to-ember-simple-auth-1.0.html)\n* [API Documentation](http://ember-simple-auth.com/api/)\n\n## What does it do?\n\n* it __maintains a client side session__ and synchronizes its state across\n  multiple tabs/windows of the application\n* it __authenticates the session__ against the application's own server,\n  external providers like Facebook etc.\n* it is __easily customizable and extensible__\n\n## How does it work?\n\nEmber Simple Auth consists of __3 main building blocks__ - the session, a\nsession store and authenticators.\n\nThe __session service is the main interface to the library__. It provides\n__methods for authenticating and invalidating the session__ as well as for\nsetting and reading session data.\n\nThe __session store persists the session state__ so that it survives a page\nreload. It also synchronizes the session state across multiple tabs or windows\nof the application so that e.g. a logout in one tab or window also results in a\nlogout in all other tabs or windows of the application.\n\n__Authenticators authenticate the session__. An application can leverage\nmultiple authenticators to support multiple ways of authentication such as\nsending credentials to the application's own backend server, Facebook, github\netc.\n\n## Example App\n\n__Ember Simple Auth comes with a\n[test app](packages/test-app/)\nthat implements a complete auth solution__ including authentication against\nthe application's own server as well as Facebook, authorization of Ember Data\nrequests and error handling. __Check out that test app for reference.__ To\nstart it, run\n\n```\ngit clone https://github.com/mainmatter/ember-simple-auth.git\ncd ember-simple-auth/packages/test-app\npnpm install \u0026\u0026 ember serve\n```\n\nand go to [http://localhost:4200](http://localhost:4200).\n\n## Installation\n\nInstalling the library is as easy as:\n\n```bash\nember install ember-simple-auth\n```\n\n### Upgrading from a pre-3.0 release?\n\nThe 3.0 release of ember-simple-auth removes previously deprecated code,\nintroducing some breaking changes, but thankfully there is an\n[v3 upgrade guide](guides/upgrade-to-v3.md).\n\n### Upgrading to 4.0 release?\n\nThe 4.1 release introduced a `session#setup` that fixes build issues for `typescript` and `embroider` users,\ndue to ESA using initializers. Consult with the guide in order to fix them\nas well as prepare yourself for v5 release which will make it **required**.\n[v4 upgrade guide](guides/upgrade-to-v4.md).\n\n### Upgrading to 7.0 release?\n\nThe 7.0 release introduces a **breaking** change, it no longer automatically provides a session service and a default session-store. You have explicitly import these files instead.\nAdditional semi-breaking change is how classes provided by us are extended.\nPlease see the guide [v7 upgrade guide](guides/upgrade-to-v7.md).\n\n## Walkthrough\n\nOnce the library is installed, import a session service and a session-store inside your application__.\n\n### Add `app/services/session.js` or `app/services/session.ts`\n```js\nimport Service from 'ember-simple-auth/services/session';\n\nexport default class SessionService extends Service {}\n```\n\n### Add `app/session-stores/application.js` or `app/session-stores/application.ts`\n```js\nimport AdaptiveStore from 'ember-simple-auth/session-stores/adaptive';\n\nexport default class SessionStore extends AdaptiveStore {}\n```\n\n#### Optional Generic `Data` argument.\n\n```ts\nimport Service from 'ember-simple-auth/services/session';\n\ntype Data = {\n  authenticated: {\n    // Any data your authenticators return\n    id: string;\n  }\n}\n\nexport default class SessionService extends Service\u003cData\u003e {}\n```\n\nthen __the session service can be injected wherever\nneeded in the application__. In order to display login/logout buttons depending\non the current session state, inject the service into the respective controller\nor component and __query its\n[`isAuthenticated` property](http://ember-simple-auth.com/api/SessionService.html#property_isAuthenticated)\nin the template__:\n\n```js\n// app/controllers/application.js\nimport Controller from '@ember/controller';\nimport { service } from '@ember/service';\n\nexport default class ApplicationController extends Controller {\n  @service session;\n\n  …\n}\n```\n\n```handlebars\n{{!-- app/templates/application.hbs --}}\n\u003cdiv class=\"menu\"\u003e\n  …\n  {{#if this.session.isAuthenticated}}\n    \u003ca {{on \"click\" this.invalidateSession}}\u003eLogout\u003c/a\u003e\n  {{else}}\n    {{#link-to 'login'}}Login{{/link-to}}\n  {{/if}}\n\u003c/div\u003e\n\u003cdiv class=\"main\"\u003e\n  {{outlet}}\n\u003c/div\u003e\n```\n\nIn the `invalidateSession` action __call the\n[session service's `invalidate` method](http://ember-simple-auth.com/api/SessionService.html#method_invalidate)\nto invalidate the session__ and log the user out:\n\n```js\n// app/controllers/application.js\nimport Controller from '@ember/controller';\nimport { service } from '@ember/service';\nimport { action } from \"@ember/object\";\n\nexport default class ApplicationController extends Controller {\n  @service session;\n\n  …\n\n  @action\n  invalidateSession() {\n    this.session.invalidate();\n  }\n}\n```\n\nFor authenticating the session, __the session service provides the\n[`authenticate` method](http://ember-simple-auth.com/api/SessionService.html#method_authenticate)__\nthat takes the name of the authenticator to use as well as other arguments\ndepending on specific authenticator used. __To define an authenticator, add a\nnew file in `app/authenticators`__ and extend one of the authenticators the\nlibrary comes with, e.g.:\n\n```js\n// app/authenticators/oauth2.js\nimport OAuth2PasswordGrant from 'ember-simple-auth/authenticators/oauth2-password-grant';\n\nexport default class OAuth2Authenticator extends OAuth2PasswordGrant {}\n```\n\nWith that authenticator and a login form like\n\n```handlebars\n{{!-- app/templates/login.hbs --}}\n\u003cform {{on \"submit\" this.authenticate}}\u003e\n  \u003clabel for=\"identification\"\u003eLogin\u003c/label\u003e\n  \u003cinput id='identification' placeholder=\"Enter Login\" value={{this.identification}} {{on \"change\" this.updateIdentification}}\u003e\n  \u003clabel for=\"password\"\u003ePassword\u003c/label\u003e\n  \u003cinput id='password' placeholder=\"Enter Password\" value={{this.password}} {{on \"change\" this.updatePassword}}\u003e\n  \u003cbutton type=\"submit\"\u003eLogin\u003c/button\u003e\n  {{#if this.errorMessage}}\n    \u003cp\u003e{{this.errorMessage}}\u003c/p\u003e\n  {{/if}}\n\u003c/form\u003e\n```\n\nthe __session can be authenticated with the\n[session service's `authenticate` method](http://ember-simple-auth.com/api/SessionService.html#method_authenticate)__:\n\n```js\n// app/controllers/login.js\nimport Controller from '@ember/controller';\nimport { service } from '@ember/service';\nimport { action } from \"@ember/object\";\nimport { tracked } from \"@glimmer/tracking\";\n\nexport default class LoginController extends Controller {\n  @tracked errorMessage;\n  @service session;\n\n  @action\n  async authenticate(e) {\n    e.preventDefault();\n    let { identification, password } = this;\n    try {\n      await this.session.authenticate('authenticator:oauth2', identification, password);\n    } catch(error) {\n      this.errorMessage = error.error || error;\n    }\n\n    if (this.session.isAuthenticated) {\n      // What to do with all this success?\n    }\n  }\n\n  @action\n  updateIdentification(e) {\n    this.identification = e.target.value;\n  }\n\n  @action\n  updatePassword(e) {\n    this.password = e.target.value;\n  }\n}\n```\n\n__To make a route in the application accessible only when the session is\nauthenticated__, call the session service's\n[`requireAuthentication`](http://ember-simple-auth.com/api/SessionService.html#method_requireAuthentication)\nmethod in the respective route's  `beforeModel` method:\n\n```js\n// app/routes/authenticated.js\nimport Route from '@ember/routing/route';\nimport { service } from '@ember/service';\n\nexport default class AuthenticatedRoute extends Route {\n  @service session;\n\n  beforeModel(transition) {\n    this.session.requireAuthentication(transition, 'login');\n  }\n}\n```\n\nThis will make the route (and all of its subroutes) transition to the `login`\nroute if the session is not authenticated. Add the `login` route in the router\nlike this:\n\n```js\n// app/router.js\nRouter.map(function() {\n  this.route('login');\n});\n```\n\nIt is recommended to nest all of an application's routes that require the\nsession to be authenticated under a common parent route:\n\n```js\n// app/router.js\nRouter.map(function() {\n  this.route('login');\n  this.route('authenticated', { path: '' }, function() {\n    // all routes that require the session to be authenticated\n  });\n});\n```\n\nTo prevent a route from being accessed when the session is authenticated (which\nmakes sense for login and registration routes for example), call the session\nservice's\n[`prohibitAuthentication`](http://ember-simple-auth.com/api/SessionService.html#method_prohibitAuthentication)\nmethod in the respective route's `beforeModel` method:\n\n```js\n// app/routes/login.js\nimport Route from '@ember/routing/route';\nimport { service } from '@ember/service';\n\nexport default class LoginRoute extends Route {\n  @service session;\n\n  beforeModel(transition) {\n    this.session.prohibitAuthentication('index');\n  }\n}\n```\n\n__The session service also provides the\n[`handleAuthentication`](http://ember-simple-auth.com/api/SessionService.html#method_handleAuthentication)\nand\n[`handleInvalidation`](http://ember-simple-auth.com/api/SessionService.html#method_handleInvalidation)\nmethods__ for handling authentication and invalidation of the session (which\nnot only happens when the user submits the login form or clicks the logout\nbutton but also when the session is authenticated or invalidated in another tab\nor window of the application). The `handleAuthentication` method will\ntransition to a configurable route while the `handleInvalidation` method will\nreload the page to clear all potentially sensitive data from memory. In order\nto customize those behaviours, these methods can be overridden when the\napplication defines its own session service that extends the one provided by\nEmber Simple Auth.\n\nTo add authorization information to requests, you can use the session service\nto check if the session is authenticated and access\nauthentication/authorization data, e.g. a token:\n\n```js\n// app/adapters/application.js\nimport JSONAPIAdapter from '@ember-data/adapter/json-api';\nimport { computed } from '@ember/object';\nimport { service } from '@ember/service';\n\nexport default class ApplicationAdapter extends JSONAPIAdapter {\n  @service session;\n\n  @computed('session.{data.authenticated.access_token,isAuthenticated}')\n  get headers() {\n    let headers = {};\n    if (this.session.isAuthenticated) {\n      // OAuth 2\n      headers['Authorization'] = `Bearer ${this.session.data.authenticated.access_token}`;\n    }\n\n    return headers;\n  }\n}\n```\n\n## The Session Service\n\nThe session service is the main interface to the library. It defines the\n`authenticate`, `invalidate` and `authorize` methods as well as the session\nevents as shown above.\n\nIt also provides the\n__[`isAuthenticated`](http://ember-simple-auth.com/api/SessionService.html#property_isAuthenticated)\nas well as the\n[`data`]((http://ember-simple-auth.com/api/SessionService.html#data))\nproperties. The latter can be used to get and set the session data__. While the\nspecial `authenticated` section in the session data contains the data that was\nacquired by the authenticator when it authenticated the session and is\nread-only, all other session data can be written and will also remain in the\nsession after it is invalidated. It can be used to store all kinds of client\nside data that needs to be persisted and synchronized across tabs and windows,\ne.g.:\n\n```js\nthis.session.set('data.locale', 'de');\n```\n\n## Authenticators\n\n__Authenticators implement the concrete steps necessary to authenticate the\nsession.__ An application can leverage several authenticators for different\nkinds of authentication mechanisms (e.g. the application's own backend server,\nexternal authentication providers like Facebook etc.) while the session is only\never authenticated with one authenticator at a time. The authenticator to use\nis chosen when authentication is triggered via the name it is registered with\nin the Ember container:\n\n```js\nthis.session.authenticate('authenticator:some');\n```\n\nEmber Simple Auth comes with 4 authenticators:\n\n* [`OAuth2PasswordGrantAuthenticator`](http://ember-simple-auth.com/api/OAuth2PasswordGrantAuthenticator.html): an OAuth 2.0 authenticator that implements the _\"Resource Owner Password Credentials Grant Type\"_\n* [`OAuth2ImplicitGrantAuthenticator`](https://ember-simple-auth.com/api/module-ember-simple-auth_authenticators_oauth2-implicit-grant-OAuth2ImplicitGrantAuthenticator.html): an OAuth 2.0 authenticator that implements the _\"Implicit Grant Type\"_\n* [`DeviseAuthenticator`](http://ember-simple-auth.com/api/DeviseAuthenticator.html): an authenticator compatible with the popular Ruby on Rails authentication plugin [devise](https://github.com/plataformatec/devise)\n* [`ToriiAuthenticator`](http://ember-simple-auth.com/api/ToriiAuthenticator.html): an authenticator that wraps the [torii library](https://github.com/Vestorly/torii)\n\nTo use any of these authenticators in an application, define a new\nauthenticator in `app/authenticators`, extend if from the Ember Simple Auth\nauthenticator\n\n```js\n// app/authenticators/oauth2.js\nimport OAuth2PasswordGrantAuthenticator from 'ember-simple-auth/authenticators/oauth2-password-grant';\n\nexport default class OAuth2Authenticator extends OAuth2PasswordGrantAuthenticator {}\n```\n\nand invoke the session service's `authenticate` method with the respective\nname, specifying more arguments as needed by the authenticator:\n\n```js\nthis.session.authenticate('authenticator:some', data);\n```\n\n### Customizing an Authenticator\n\nAuthenticators are easily customized by setting the respective properties,\ne.g.:\n\n```js\n// app/authenticators/oauth2.js\nimport OAuth2PasswordGrantAuthenticator from 'ember-simple-auth/authenticators/oauth2-password-grant';\n\nexport default class OAuth2Authenticator extends OAuth2PasswordGrantAuthenticator {\n  serverTokenEndpoint = '/custom/endpoint';\n}\n```\n\n### Implementing a custom Authenticator\n\nBesides extending one of the predefined authenticators, an application can also\nimplement fully custom authenticators. In order to do that, extend the\n[abstract base authenticator](http://ember-simple-auth.com/api/BaseAuthenticator.html)\nthat Ember Simple Auth comes with and override the\n[`authenticate`](http://ember-simple-auth.com/api/BaseAuthenticator.html#method_authenticate),\n[`restore`](http://ember-simple-auth.com/api/BaseAuthenticator.html#method_restore)\nand (optionally)\n[`invalidate`](http://ember-simple-auth.com/api/BaseAuthenticator.html#method_invalidate)\nmethods:\n\n```js\n// app/authenticators/custom.js\nimport Base from 'ember-simple-auth/authenticators/base';\n\nexport default class CustomAuthenticator extends Base {\n  restore(data) {\n    …\n  }\n\n  authenticate(options) {\n    …\n  }\n\n  invalidate(data) {\n    …\n  }\n}\n```\n\n## Session Stores\n\nEmber Simple Auth __persists the session state via a session store so it\nsurvives page reloads__. There is only one store per application that can be\ndefined in `app/session-stores/application.js`:\n\n```js\n// app/session-stores/application.js\nimport Cookie from 'ember-simple-auth/session-stores/cookie';\n\nexport default class ApplicationSessionStore extends Cookie {}\n```\n\nIf the application does not define a session store, the adaptive store which\nuses `localStorage` if that is available or a cookie if it is not, will be used\nby default. To customize the adaptive store, define a custom store in\n`app/session-stores/application.js` that extends it and overrides the\nproperties to customize.\n\n### Store Types\n\nEmber Simple Auth comes with 4 stores:\n\n#### Adaptive Store\n\n[The adaptive store](http://ember-simple-auth.com/api/AdaptiveStore.html)\nstores its data in the browser's `localStorage` if that is available or in a\ncookie if it is not; __this is the default store__.\n\n#### `localStorage` Store\n\n[The `localStorage` store](http://ember-simple-auth.com/api/LocalStorageStore.html)\nstores its data in the browser's `localStorage`. This is used by the adaptive\nstore if `localStorage` is available.\n\n#### Cookie Store\n\n[The Cookie store](http://ember-simple-auth.com/api/CookieStore.html)\nstores its data in a cookie. This is used by the adaptive store if\n`localStorage` is not available. __This store must be used when the\napplication uses\n[FastBoot](https://github.com/ember-fastboot/ember-cli-fastboot).__\n\n#### `sessionStorage` Store\n\n[The `sessionStorage` store](http://ember-simple-auth.com/api/SessionStorageStore.html)\nstores its data in the browser's `sessionStorage`. See [the Web Storage docs](\nhttps://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API) for details on\n`sessionStorage` and `localStorage`. [caniuse](http://caniuse.com/#feat=namevalue-storage)\nhas up-to-date information on browser support of `sessionStorage` and `localStorage`.\n\n#### Ephemeral Store\n\n[The ephemeral store](http://ember-simple-auth.com/api/EphemeralStore.html)\nstores its data in memory and thus __is not actually persistent. This store is\nmainly useful for testing.__ Also the ephemeral store cannot keep multiple tabs\nor windows in sync as tabs/windows cannot share memory.\n\n### Customizing the Store\n\nThe session store is easily customized by setting the respective properties,\ne.g.:\n\n```js\n// app/session-stores/application.js\nimport AdaptiveStore from 'ember-simple-auth/session-stores/adaptive';\n\nexport default class ApplicationSessionStore extends AdaptiveStore {\n  cookieName = 'my-apps-session-cookie';\n}\n```\n\n### Implementing a custom Store\n\nBesides using one of the predefined session stores, an application can also\nimplement fully custom stores. In order to do that, extend the\n[abstract base session store](http://ember-simple-auth.com/api/BaseStore.html)\nthat Ember Simple Auth comes with and implement the\n[`persist`](http://ember-simple-auth.com/api/BaseStore.html#.persist),\n[`restore`](http://ember-simple-auth.com/api/BaseStore.html#.restore)\nand\n[`clear`](http://ember-simple-auth.com/api/BaseStore.html#.clear)\nmethods:\n\n```js\n// app/session-stores/application.js\nimport Base from 'ember-simple-auth/session-stores/base';\n\nexport default class ApplicationSessionStore extends Base {\n  persist() {\n    …\n  }\n\n  restore() {\n    …\n  }\n}\n```\n\n## FastBoot\n\nEmber Simple Auth works with FastBoot out of the box as long as the Cookie\nsession store is being used. In order to enable the cookie store, define it as\nthe application store:\n\n```js\n// app/session-stores/application.js\nimport CookieStore from 'ember-simple-auth/session-stores/cookie';\n\nexport default class ApplicationSessionStore extends CookieStore {}\n```\n\nIf you are using the\n[`OAuth2PasswordGrantAuthenticator`](http://ember-simple-auth.com/api/OAuth2PasswordGrantAuthenticator.html),\nor\n[`DeviseAuthenticator`](http://ember-simple-auth.com/api/DeviseAuthenticator.html),\nyou must add `node-fetch` to your list of FastBoot whitelisted dependencies\nin `package.json`:\n\n```json\n{\n  \"fastbootDependencies\": [\n    \"node-fetch\"\n  ]\n}\n```\n\n## Engines\n\nEmber Simple Auth works with engines out of the box. The host app and any\nengine(s) share the same `session` service so they can synchronize the\nauthentication status:\n\n```js\n// my-engine/addon/routes/index.js\nimport Application from '@ember/application';\nimport loadInitializers from 'ember-load-initializers';\n\nclass App extends Application {\n  …\n\n  engines = {\n    'my-engine': {\n      dependencies: {\n        services: [\n          'session'\n        ]\n      }\n    }\n  }\n});\n\n…\n\nexport default App;\n\n```\n\nThe session can then be authenticated or invalidated from the host app or any\nof the engines and the state will be synchronized via the service.\n\nOne thing to be aware of is that if the authentication route is outside of the\nengine (e.g. in the host app), it is necessary to use the special\n`transitionToExternal` method in the engine to transition to it. That can be\ndone by passing a callback instead of a route name to the session service's\n`requireAuthentication` method in that case:\n\n```js\n// my-engine/addon/routes/index.js\nimport Route from '@ember/routing/route';\nimport { service } from '@ember/service';\n\nexport default class IndexRoute extends Route {\n  @service session;\n\n  beforeModel(transition) {\n    this.session.requireAuthentication(transition, () =\u003e this.transitionToExternal('login'));\n  },\n}\n```\n\n## Testing\n\nEmber Simple Auth comes with a __set of test helpers that can be used in acceptance tests__.\n\nOur helpers use the [more modern testing syntax](https://dockyard.com/blog/2018/01/11/modern-ember-testing)\nand therefore require `ember-cli-qunit` [4.2.0 or greater](https://github.com/ember-cli/ember-cli-qunit/blob/master/CHANGELOG.md#v420-2017-12-17)\nor `ember-qunit` 3.2.0 or greater.\n\nWe provide the following helpers:\n* `currentSession()` returns the current session.\n* `authenticateSession(sessionData)` authenticates the session asynchronously;\n  the optional `sessionData` argument can be used to mock the response of an\n  authentication request, to provide a specific authorization token or user\n  data.\n* `invalidateSession()` invalidates the session asynchronously.\n\nWhich can be used as shown in the following example:\n\n```js\nimport { module, test } from 'qunit';\nimport { visit, currentURL } from '@ember/test-helpers';\nimport { setupApplicationTest } from 'ember-qunit';\nimport { currentSession, authenticateSession, invalidateSession } from 'ember-simple-auth/test-support';\n\nmodule('Acceptance | app test', function(hooks) {\n  setupApplicationTest(hooks);\n\n  test('/login redirects to index if user is alread logged in', async function(assert) {\n    await authenticateSession({\n      authToken: '12345',\n      otherData: 'some-data'\n    });\n    await visit('/login');\n\n    assert.equal(currentURL(), '/');\n\n    let sessionData = currentSession().get('data.authenticated');\n    assert.equal(sessionData.authToken, '12345');\n    assert.equal(sessionData.otherData, 'some-data');\n  });\n\n  test('/protected redirects to /login if user is not logged in', async function(assert) {\n    await invalidateSession();\n\n    await visit('/protected');\n\n    assert.equal(currentURL(), '/login');\n  });\n});\n```\n\nIf you're an `ember-mocha` user, we can recommend to check out this\n[example from the test suite of ember-simple-auth itself](https://github.com/mainmatter/ember-simple-auth/blob/master/packages/test-app/tests/acceptance/authentication-test.js).\n\n## Other guides\n\n* [Managing current User](guides/managing-current-user.md)\n* [Upgrading to v7](guides/upgrade-to-v7.md)\n* [Upgrading to v4](guides/upgrade-to-v4.md)\n* [Upgrading to v3](guides/upgrade-to-v3.md)\n\n## License\n\nEmber Simple Auth is developed by and \u0026copy;\n[Mainmatter GmbH](http://mainmatter.com) and contributors. It is\nreleased under the\n[MIT License](LICENSE).\n\nEmber Simple Auth is not an official part of [Ember.js](http://emberjs.com) and\nis not maintained by the Ember.js Core Team.\n","funding_links":[],"categories":["Packages"],"sub_categories":["Authentication"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmainmatter%2Fember-simple-auth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmainmatter%2Fember-simple-auth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmainmatter%2Fember-simple-auth/lists"}