ember-cli simple-auth custom authorization - ember.js

i am trying to use ember-simple-auth with custom authentication and authorization: authenticator works but authorizer doesn't. Token successfully assigned but there is no injection in ajax calls.
app/authenticator/custom.js
import Ember from 'ember';
import Base from 'simple-auth/authenticators/base';
export default Base.extend({
tokenEndpoint: 'http://...',
restore: function(data) {
return new Ember.RSVP.Promise(function(resolve, reject) {
if (!Ember.isEmpty(data.token)) {
resolve(data);
} else {
reject();
}
});
},
authenticate: function(credentials) {
var _this = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
Ember.$.ajax({
url: _this.tokenEndpoint,
type: 'POST',
data: JSON.stringify({ username: credentials.identification, password: credentials.password }),
contentType: 'application/json'
}).then(function(response) {
Ember.run(function() {
resolve({ token: response.token });
});
}, function(xhr, status, error) {
var response = JSON.parse(xhr.responseText);
Ember.run(function() {
reject(response.error);
});
});
});
},
invalidate: function() {
var _this = this;
return new Ember.RSVP.Promise(function(resolve) {
Ember.$.ajax({ url: _this.tokenEndpoint, type: 'DELETE' }).always(function() {
resolve();
});
});
},
});
app/authorizers/custom.js
import Ember from 'ember';
import Base from 'simple-auth/authorizers/base';
export default Base.extend({
authorize: function(jqXHR, requestOptions) {
if (this.get('session.isAuthenticated') && !Ember.isEmpty(this.get('session.secure.token'))) {
jqXHR.setRequestHeader('X-CSRFToken', this.get('session.secure.token'));
}
}
});
app/initializers/authentication.js
import CustomAuthenticator from 'app/authenticators/custom';
import CustomAuthorizer from 'app/authorizers/custom';
export default {
name: 'authentication',
before: 'simple-auth',
initialize: function(container) {
container.register('authenticator:custom', CustomAuthenticator);
container.register('authorizer:custom', CustomAuthorizer);
}
};
config/environment.js
ENV['simple-auth'] = {
authorizer: 'authorizer:custom',
crossOriginWhitelist: ['http://...']
};
app/controllers/login.js
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
authenticate: function(){
var credentials = this.getProperties('identification', 'password');
this.get('session').authenticate('authenticator:custom', credentials);
}
}
});

Related

How in ember-simple-auth change "username" in request body to _username and password to _password

I can change it inside module, but after "npm install" this changes are discarded
You should create your own authenticator like that one I have created to authenticate the user with my backend. I specified the fields that I want to send in my request in the "authenticate" function:
import Ember from 'ember';
import Base from 'ember-simple-auth/authenticators/base';
import request from 'ic-ajax';
export default Base.extend({
tokenEndPoint: 'http://localhost:3000/api/sessions',
restore: function(data) {
return new Ember.RSVP.Promise(function(resolve, reject){
if(!Ember.isEmpty(data.token)) {
resolve(data);
} else {
reject();
}
});
},
authenticate: function(options) {
return new Ember.RSVP.Promise((resolve, reject) => {
Ember.$.ajax({
url: this.tokenEndPoint,
type: 'POST',
crossDomain: true,
data: JSON.stringify({
session: {
_email: options.session.email,
_password: options.session.password
}
}),
contentType: 'application/json'
// dataType: 'json'
}).then(function(response){
console.log('LOGIN OK: ' + response.auth_token);
Ember.run(function(){
resolve({
token: response.auth_token
});
});
}, function(xhr, status, error) {
console.log('LOGIN ERROR: ' + xhr.responseText);
var response = xhr.responseText;
Ember.run(function(){
reject(response);
});
});
});
},
invalidate: function() {
console.log('Invalidate Session....');
return Ember.RSVP.resolve();
}
});

Ember simple auth 1.0.1 custom authenticator

I am updating my existing code done in ember-simple-auth: 0.8.0 to ember-simple-auth: 1.0.1
There are two problems
It is not persisting a session
REST Calls needed to be having withCredentials: true, not sure where I can set them.
Here is my code
//config/environment.js
ENV['ember-simple-auth'] = {
store: 'simple-auth-session-store:local-storage',
authorizer: 'authorizer:custom',
routeAfterAuthentication: '/dashboard',
routeIfAlreadyAuthenticated: '/dashboard'
};
My authenticator
//authenticators/custom.js
import Ember from 'ember';
import Base from 'ember-simple-auth/authenticators/base';
import config from '../config/environment';
export default Base.extend({
restore(data) {
return new Ember.RSVP.Promise(function (resolve, reject) {
if (!Ember.isEmpty(data.token)) {
resolve(data);
}
else {
reject();
}
});
},
authenticate(options) {
return new Ember.RSVP.Promise(function(resolve, reject) {
Ember.$.ajax({
type: "POST",
url: config.serverURL + '/api/users/login',
data: JSON.stringify({
username: options.identification,
password: options.password
}),
contentType: 'application/json;charset=utf-8',
dataType: 'json'
}).then(function(response) {
Ember.run(function() {
resolve(response);
});
}, function(xhr) {
Ember.run(function() {
reject(xhr.responseJSON || xhr.responseText);
});
});
});
},
invalidate(data) {
return new Ember.RSVP.Promise(function(resolve, reject) {
Ember.$.ajax({
type: "POST",
url: config.serverURL + '/api/users/logout'
}).then(function(response) {
Ember.run(function() {
resolve(response);
});
}, function(xhr) {
Ember.run(function() {
reject(xhr.responseJSON || xhr.responseText);
});
});
});
}
});
My authorizer (you can see that I am trying to update my old code)
//authorizers/custom.js
import Ember from 'ember';
import Base from 'ember-simple-auth/authorizers/base';
export default Base.extend({
authorize(sessionData, block) {
if (!Ember.isEmpty(sessionData.token)) {
block('X-CSRF-Token', sessionData.token);
block('Content-Type', 'application/json;charset=utf-8');
block('withCredentials', true);
}
}
//authorize(jqXHR, requestOptions) {
// if (!(requestOptions.data instanceof FormData)){
// requestOptions.contentType = 'application/json;charset=utf-8';
// }
//
// requestOptions.crossDomain = true;
// requestOptions.xhrFields = {
// withCredentials: true
// };
//
//
// var token = this.get('session.token');
// console.error(jqXHR);
// if (this.get('session.isAuthenticated') ) {
// jqXHR.setRequestHeader('X-CSRF-Token', token);
// }
//}
});
My application adapter
import DS from 'ember-data';
import config from '../../config/environment';
import DataAdapterMixin from 'ember-simple-auth/mixins/data-adapter-mixin';
export default DS.RESTAdapter.extend(DataAdapterMixin, {
authorizer: 'authorizer:custom',
namespace: 'api',
host: config.serverURL,
});
Dashboard
import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
session: Ember.inject.service('session'),
needs: 'application',
setupController: function(controller, model){
this.controllerFor('application').set('pageTitle', 'Dashboard');
this._super(controller, model);
}
});
If I do console.log(this.get('session.isAuthenticated'); it returns me true, but when I use that in template it dont work
{{#if session.isAuthenticated}}
1
{{else}}
0
{{/if}}
On my laravel end, i can see that session is created and user is logged in, on Ember side, it was previously setting the session and then resends the credentials with each request. Now when it send another request. I think it is without credentials: True and laravel returns 401. I also tried sending a garbage header and laravel CORS refused that it is not in allowed headers.
Thank you
The authorizer config setting doesn't exist anymore in 1.0 as auto-authorization has been dropped. See the API docs for info on how to add authorization to outgoing requests:
http://ember-simple-auth.com/api/classes/SessionService.html#method_authorize
http://ember-simple-auth.com/api/classes/DataAdapterMixin.html
Also your authorizer should not call the block several times but only ones, passing all authorization data at once.
Also make sure you inject the session service into all controllers and components for templates you use the session in.

Empty model in Route

I have the following route:
import Ember from 'ember';
export default Ember.Route.extend({
ajax: Ember.inject.service(),
queryParams: {
search: {
refreshModel: true
}
},
beforeModel: function() {
var params = this.paramsFor('recipes');
var that = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
that.get('ajax').request({
url: "/recipes",
method: "GET",
data: {
namePart: params.search
}
},
function(response) {
that.store.unloadAll("recipe");
response.forEach(function(item) {
that.store.push(that.store.normalize("recipe", item));
});
resolve();
});
});
},
model: function() {
this.store.peekAll('recipe');
}
});
And controller:
import Ember from 'ember';
export default Ember.Controller.extend({
queryParams: ['search'],
search: null
});
The request is successful. And I even see appropriate data in the store. But route/controller model is null. What I'm doing wrong?
You're missing return keyword in model:
model() {
return this.store.peekAll('recipe');
}

Ember-simple-auth with laravel

I'm having trouble creating a custom authenticator for my laravel backend. I'm not sure if this is the correct custom authenticator for laravel, but I'm using this as a starting point (https://github.com/simplabs/ember-simple-auth/blob/master/examples/6-custom-server.html).
My Ember.SimpleAuth is undefined. Here is what I have in my app.js.
import Ember from 'ember';
import Resolver from 'ember/resolver';
import loadInitializers from 'ember/load-initializers';
Ember.MODEL_FACTORY_INJECTIONS = true;
window.ENV = window.ENV || {};
window.ENV['simple-auth'] = {
authorizer: 'authorizer:custom'
};
Ember.Application.initializer({
name: 'authentication',
before: 'simple-auth',
initialize: function(container, application) {
//register the laravel authenticator so the session can find it
container.register('authenticator:laravel', App.LaravelAuthenticator);
container.register('authorizer:custom', App.CustomAuthorizer);
}
});
var App = Ember.Application.extend({
modulePrefix: 'ember-simple-auth-sample', // TODO: loaded via config
Resolver: Resolver
});
App.LaravelAuthenticator = Ember.SimpleAuth.Authenticators.Base.extend({
tokenEndpoint: '/v4/session',
restore: function(data) {
return new Ember.RSVP.Promise(function(resolve, reject) {
if (!Ember.isEmpty(data.token)) {
resolve(data);
} else {
reject();
}
});
},
authenticate: function(credentials) {
var _this = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
Ember.$.ajax({
url: _this.tokenEndpoint,
type: 'POST',
data: JSON.stringify({ session: { identification: credentials.identification, password: credentials.password } }),
contentType: 'application/json'
}).then(function(response) {
Ember.run(function() {
resolve({ token: response.session.token });
});
}, function(xhr, status, error) {
var response = JSON.parse(xhr.responseText);
Ember.run(function() {
reject(response.error);
});
});
});
},
invalidate: function() {
var _this = this;
return new Ember.RSVP.Promise(function(resolve) {
Ember.$.ajax({ url: _this.tokenEndpoint, type: 'DELETE' }).always(function() {
resolve();
});
});
}
});
// the custom authorizer that authorizes requests against the custom server
App.CustomAuthorizer = Ember.SimpleAuth.Authorizers.Base.extend({
authorize: function(jqXHR, requestOptions) {
if (this.get('session.isAuthenticated') && !Ember.isEmpty(this.get('session.token'))) {
jqXHR.setRequestHeader('Authorization', 'Token: ' + this.get('session.token'));
}
}
});
loadInitializers(App, 'ember-simple-auth-sample');
export default App;
Ember.SimpleAuth doesn't exist anymore, it now has it's own global SimpleAuth when you use the browserified distribution. It looks like you're using ember-cli though which means you're using the AMD distribution of Ember Simple Auth anyway which doesn't define any global at all. For instructions on how to use Ember Simple Auth with ember-cli see this blog post.
Apart from that your authenticator and authorizer look fine on first glance and should generally work that way.

Ember-cli - Simple-Auth :: Location for factory authenticator:custom

Where is the proper location for factory in ember-cli. Once I have the proper location for the factory, do I register in my initializer as such
container.register('authenticator:custom', application.CustomAuthenticator);
// the custom authenticator that authenticates the session against the custom server
App.CustomAuthenticator = Ember.SimpleAuth.Authenticators.Base.extend({
tokenEndpoint: '/v4/session',
restore: function(data) {
return new Ember.RSVP.Promise(function(resolve, reject) {
if (!Ember.isEmpty(data.token)) {
resolve(data);
} else {
reject();
}
});
},
authenticate: function(credentials) {
var _this = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
Ember.$.ajax({
url: _this.tokenEndpoint,
type: 'POST',
data: JSON.stringify({ session: { identification: credentials.identification, password: credentials.password } }),
contentType: 'application/json'
}).then(function(response) {
Ember.run(function() {
resolve({ token: response.session.token });
});
},
function(xhr, status, error) {
var response = JSON.parse(xhr.responseText);
Ember.run(function() {
reject(response.error);
});
});
});
},
invalidate: function() {
var _this = this;
return new Ember.RSVP.Promise(function(resolve) {
Ember.$.ajax({ url: _this.tokenEndpoint, type: 'DELETE' }).always(function() {
resolve();
});
});
},
});
Thanks!
Yes, that's how you do it. Make sure though to call container.register before you fall Ember.SimpleAuth.setup.