This question is related to: Does Ember Octane Route class support using mixins? Mixins are officially deprecated in Ember Octane.
Question:
What is the best option to replace Ember mixins with and how do I implement it?
Context:
I have custom mixins that expand functionality offered by ember-simple-auth (~v1.8.2), which was not available at the time the methods were created (see below). I am currently using ember-simple-auth 3.0.0 https://github.com/simplabs/ember-simple-auth. In the documentation on github, they appear to be using their own mixins on Ember Octane as you can see:
// my-engine/addon/routes/index.js
import Route from '#ember/routing/route';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default class IndexRoute extends Route.extend(AuthenticatedRouteMixin) {
triggerAuthentication() {
this.transitionToExternal('login');
}
}
It appears that I am not the only one having this issue as Simple Auth doesn't know what route they want to go down either: https://github.com/simplabs/ember-simple-auth/issues/2185
Options:
Pure native classes, sharing functionality via class inheritance.
Utility functions which can be imported and used in multiple classes.
Services which can be injected into multiple classes, sharing
functionality and state between them.
I have the following authentication mixins:
Application Route: This handles whether the user is logged in and whether the user has two-factor authentication (2FA) enabled, and if it is enabled, it verifies that the user has been authenticated through 2FA. This is because simple auth did not offer 2FA at the time of development of the mixin(s)
Authenticated Route: Makes sure the user is logged in. If they are not logged in then the user is routed to the login page. Once they login, they are routed back to the page that they initially tried to go to
UnAuthenticated Route: Prevents logged in users from going to certain routes that logged in users should not go to
Firstly I want to make very clear that mixins are not "officially deprecated" in Ember, and to my knowledge there's not even an active RFC about it. As the Upgrade Guides explain, Glimmer components do not support mixins due to not extending EmberObject, but the pre-existing framework classes (Route, Controller, etc) necessarily have to or it would be a breaking change.
There is no best option to replace mixins as it depends on the usage of the API. If you are asking how to replace ember-simple-auth mixins, my answer is that you can't until the addon itself provides alternative APIs. Mixins and the example code you posted will continue working for the foreseeable future.
You can see an example of using class inheritance to share functionality in this PR.
when i migrated to ember Octane i tried to replace ember-simple-auth mixins, i found that it would take me lot of time than rewriting my own authentication service, my example in this twiddle, i am using cookies, Auth service
if you are not using cookies , you could customize your adapter to include a token in the headers
I circled back with ESA on Git, and the same issue I cited in my OP has been closed with a new issue that has subsequently been merged:
https://github.com/simplabs/ember-simple-auth/pull/2198
ESA has now updated their library to get rid of route mixins.
Related
The django rest framework does allow per view authentication schemes:
http://www.django-rest-framework.org/api-guide/authentication/#setting-the-authentication-scheme
I think this is handy and I ask myself why this gets reinvented in the django rest framework.
"Why does django not provide this?" is a question which would get closed here on stackoverflow soon.
That's why I ask:
How to get per view authentication schemes in django?
"Why does django not provide this?"
It's an opinion. I don't see why someone should limit a specific view to some authentication backends. Whatever my/your opinion is, the decision is made in Django/DRF. Contact their mailing list and search their bug repo to find out why a specific decision made.
How to get per view authentication schemes in django?
Before anything be sure you know how Django works. Read all authentication related documents like this and this.
You could go the DRF way: Completely ditch Django authentication and write it yourself. Replace Django authentication backend abstract with your desired one and make a way to configure each view (e.g. Use a decorator to set attributes on you view function or use class based views + some fields). Then add a middleware to authenticate users and replace Django's AuthenticationMiddleware to provide request.user. You should also make sure that things like login_required work without modification or you should provide an alternative.
I'm creating a basic Ember application. I am trying to set up a backend that stores posts. I would like to have a system where I can go to some admin site that has a form that has all the fields for a post that allows me to add, update, and delete posts. For example, if I have a Post model with attributes like Title, Contents, Date_created, and Image, I would like to have these fields in a form in some kind of admin site.
One example from a past tutorial I have done is the Django admin site. Is it possible to set up a Django backend for my Ember app? The Django admin is here: (scroll to bottom)
https://docs.djangoproject.com/en/1.10/intro/tutorial02/
I know that asking how to set up a backend for my Ember application is a very general question, but I am confused as to where to start. I have already created a Post model with various attributes. I can create an Ember route that is a form to add a post, but then there comes authentication for that which I'm not really sure how to deal with either. That's why I came to Django because I remember they had a very nice admin site.
If it is not feasible to use Django to accomplish this, what are some other routes I can take to be able to get to some admin page where I can manipulate records and add new data to my website?
This is a pretty big question, but I feel your pain. Most tutorials are all, "so... just build out a rails app... or use all this long lost stubbing stuff... or here's a super outdated node server on github to use."
I would suggest breaking it down into pieces. Ember is really great, but–Yes–you need a backend. You could make a backend with Django(python), Rails(ruby), WordPress(PHP) + ember-wordpress, express or hapi(node), phoenix(elixir)- or really anything that will generate an API. You could also build an admin with Ember and then use that to send data to a service like parse or firebase. Those could get you an MVP while you learn more about how to build out a traditional back-end.
Django + http://www.django-rest-framework.org has a pretty great admin setup that builds out the admin and fields from your API specifications. I can see why people like it.
I would also mention, that ember-cli-mirage is great when you aren't sure what backend you'll have, but you need to have a mock-server to build off of.
If you can, choose something that will spit out an API with jsonAPI.
I would split this into 2 parts.
build out an Ember app with Mirage or some other temporary data.
build a back-end somehow.
Then you can connect them ~ without being stuck beforehand.
Good luck!
So pretty much a blog site where only person can create/delete/edit posts? If so then all you have to do is create a user with a predefined username and password in your Django app. You login through your Ember app. For this protected view you will need to use ember-simple-auth, which is the simplest way to implement something like this. Google ember-simple-auth and run its dummy app to see what they are doing.
I've just finished upgrading my app to use the jj-abrams branch of ember-simple-auth (soon to be 1.0).
It's working great when I use ember data but, for one route, I use Ember.$.getJSON to retrieve chart data directly from the server.
In this instance, the authorization header is missing from the request and I'm guessing that's because it doesn't use the application adapter (therefore bypassing authorizer: 'authorizer:devise')?
Is there a way to add this header manually, or a better way to make this request?
Sure you can just include the session then you should have access to the credentials and use whatever you need to add those to your Router (I'm assuming it's using the AuthenticatedRouteMixin on your router.
Or for your controller add:
session: Ember.inject.service('session')
then you can do a get:
this.get('session')
and examine the object to find what you need in there, I believe that should make it easier for you to run without using Ember-Data.
I have properties and methods I want exposed to most/all instances of a class (i.e. all but a handful of routes, controllers, whatever). There seems to be multiple ways to accomplish this and I'm looking for guidance for best practices here.
More specifically, I've created a property on my application controller to hold a user session object. I want all other controllers to expose this data as if I had typed:
needs: ['application'],
userSession: Ember.computed.alias('controllers.application.userSession')
directly into the controller.
Further, I want to override all routes (other than the login route and maybe a couple more) implementations of beforeModel to check for the presence of userSession and redirect to the login route if absent.
This is being implemented in ember-cli FYI. So, that being the case, what's the "right" approach here? Do I try to inject these changes via initializers/services? Do I create mix-ins to do this stuff (I'm not a fan of having to remember to do that every time someone working on this does ember g controller that they then have to remember to add the mixin).
Sounds very much like the use of an initializer and a service is the best approach (them being split up makes for cleaner code). The initializer is just the code to load the service, the service does the hard work. The initializer should look something like:
import AuthService from '../services/auth';
export default {
name: 'auth-service',
initialize: function( container, app ) {
app.register( 'service:auth', AuthService, { singleton: true } );
app.inject( 'controller', 'auth', 'service:auth' );
app.inject( 'route', 'auth', 'service:auth' );
}
};
This then injects auth into every controller and route, and you should move the userSession from your application to the service.
My auth service is too big (and in my case: too specific, as it uses Firebase) to be quoting it here. I gave the gist of it in an answer yesterday: Short delay when trying to run redirect with ember route with firebase authentication
And as you mentioned it: people don't strictly need to remember to include mixins as you can override the blueprint that is used when someone does ember generate: http://www.ember-cli.com/#generators-and-blueprints
If I want to test for authorisation in a template, I can check session.isAuthenticated. How do I do that in JavaScript?
The session is injected into all routes, controllers, models and views. Thus you can always access it with
this.get('session')
Authentication status can be accessed via
this.get('session.isAuthenticated')
Also see https://github.com/simplabs/ember-simple-auth/blob/master/packages/ember-simple-auth/lib/mixins/authenticated_route_mixin.js#L33 for an example.