- Website
- Sabin Hertanu
Ember Simple Auth - how to overwrite the default transition after authentication
Ember Simple Auth is a library for implementing authentication and authorization in Ember.js applications. You're using it in your Ember app and you're migrating away from mixins, but you're not sure how you can overwrite the default transitions. You want to get it right the first time, don't you?
Here's what we're going to cover today:
- How to protect your routes
- Getting rid of the Ember Simple Auth mixins
- How you can overwrite the default transitions defined in Ember Simple Auth
If you already use Ember Simple Auth in your app but are still using the mixins, this guide is for you. I will help you set it up in a way you can get rid of the mixins and resolve all the deprecation warnings that come with them.
With Ember Simple Auth, you can define where you want to transition to, after logging in. Let's look at how you can protect the routes that need authentication. We'll also explore how to redirect the user to different routes when they log in or out.
protected
route, that wraps all routes which need authentication
Use a Here's what you need to do:
1. In the router.js
file, wrap all your routes that need authentication within a protected
route:
// app/router.js
this.route('login')
this.route('logout')
this.route('protected', { path: '/' }, function () {
this.route('todos')
this.route('projects')
})
Note: defining the { path: '/' }
will ensure that the protected
path does not appear in the URL.
2. Create a session
service that extends the Ember Simple Auth session
service:
// app/services/session.js
import { service } from '@ember/service'
import BaseSessionService from 'ember-simple-auth/services/session'
export default class SessionService extends BaseSessionService {
prohibitAuthentication(route = 'protected') {
return super.prohibitAuthentication(route)
}
handleAuthentication() {}
}
Let's break down what we did here:
First, we defined the prohibitAuthentication()
method to pass our protected
route. According to the documentation, here's what the prohibitAuthentication method does:
Checks whether the session is authenticated. If it is, it transitions to the specified route or invokes the specified callback.
It means that we can use the prohibitAuthentication()
method on public routes. For instance, the login
and logout
routes.
// app/login/route.js
import Route from '@ember/routing/route'
import { service } from '@ember/service'
export default class LoginRoute extends Route {
@service session
beforeModel() {
this.session.prohibitAuthentication()
}
}
Second, we overwrote the handleAuthentication()
method, to prevent any default transitions.
3. Create the protected
route and protect your routes
// app/protected/route.js
import Route from '@ember/routing/route'
import { service } from '@ember/service'
export default class ProtectedRoute extends Route {
@service session
beforeModel(transition) {
this.session.requireAuthentication(transition, 'login')
}
}
According to the documentation, here's what the requireAuthentication method does:
Checks whether the session is authenticated. If it is not, it transitions to the specified route or invokes the specified callback.
It is the opposite of the prohibitAuthentication()
method, the difference being the following:
prohibitAuthentication
-> transitions if the session is authenticatedrequireAuthentication
-> transitions if the session is not authenticated
4. Add your redirection after authentication logic
We can now add the authentication logic, right where we authenticate the session. Here's what this can look like:
<!-- app/components/login.hbs -->
<form {{on 'submit' (perform this.authenticateTask)}} ...attributes>
<input type='email' value={{this.email}} />
<input type='password' value={{this.password}} />
<button type='submit'>Login</button>
</form>
// app/components/login.js
import Component from '@glimmer/component'
import { tracked } from '@glimmer/tracking'
import { task } from 'ember-concurrency'
import { service } from '@ember/service'
export default class LoginComponent extends Component {
@service session
@service router
@tracked email
@tracked password
authenticateTask = task(this, { drop: true }, async () => {
let { email, password } = this;
await this.session.authenticate('authenticator:custom', { email, password })
// here is where we can define our custom redirection after authentication
this.router.transitionTo('todos')
}
}
Note: authenticator:custom
means that you've already defined a custom authenticator under app/authenticators/custom.js
. See Ember Simple Auth - BaseAuthenticator for more details on how you can create custom authenticators.
Next steps - migrate away from using Ember Simple Auth mixins
Using this approach you can get rid of the following mixins:
If you are still using the Ember Simple Auth mixins, stop right there. Follow the steps above to migrate away from them and get rid of all deprecation warnings.