mainmatter / ember-simple-auth Goto Github PK
View Code? Open in Web Editor NEWA library for implementing authentication/authorization in Ember.js applications.
Home Page: https://ember-simple-auth.com
License: MIT License
A library for implementing authentication/authorization in Ember.js applications.
Home Page: https://ember-simple-auth.com
License: MIT License
Right now the routeAfterLogout
field lets you specify a route to go to using transitionToRoute
when logout is performed. However, if you are using something like Ember Data you may want to guarantee that the data cache is also cleared on logout, just in case the user immediately logs in again. To have this happen in my own app I overrode the logout
action like this:
logout: function () {
var token = this.get('session.authToken');
jQuery.ajax({
url: apiEndpoint + '/users/auth/logout?authToken=' + token,
type: 'GET'
});
this.get('session').destroy();
location.href = './';
}
The important part for this ticket is the last line where we actually navigate to the root of the application as opposed to going to the home route through Ember. The other part allowing me to invalidate my session token on the server side is also probably a worthwhile addition.
It would be wonderful to have documentation on how to use this library with Rails. I haven't started trying to add authentication to the Rails+Ember app I'm building, and I'd love to get a hint about the right direction to go in. If you have any code snippets or general words of advice to get me started, I'd be happy to write up the documentation in the wiki myself when I figure it all out.
If I load the application on a non-protected route and then transition to a protected route, everything works normally.
However, when I load the application on the protected route, it throws the following error:
I also created a couple of jsbins:
JSbin for working example
JSbin for failing example
Unfortunately the error can not be seen in JSBin hence the screenshot. I checked this both with ember-1.0.0 and the latest canary build.
Hi I was just wondering if you could help me by recommending the best way to gain access to the currently logged in user site wide so as I can use something like this in templates {{currentUser.name}} ?
I have the token based authentication working fine using ember-appkit-rails and also has_secure_password I'm just unsure of the correct way to approach this.
Any help is greatly appreciated!
In the previous version I was able to overwrite the serverTokenEndpoint in the setup function.
This feature seems to be missing in the latest version.
Due to this I implemented it like this:
Ember.SimpleAuth.Authenticators.OAuth2 = Ember.SimpleAuth.Authenticators.OAuth2.reopen({
serverTokenEndpoint: '/api/login'
});
Is this intentional?
If the server invalidates the token, a 401 will be returned by the server on request. We need to somehow catch this, reset the session and redirect to login.
If a username or password contains special url characters, such as an ampersand, it breaks the url encoding as these characters are not properly escaped.
For example, this password:
onetwo&three
would be passed to the server as:
{
password: onetwo,
three: null
}
Rather than creating the querystring, it would be better to create a simple object in tokenRequestOptions
and let jQuery handle the details.
I've got Ember.SimpleAuth working well, thanks for creating such a great library!
One thing I've noticed is upon clicking "Login", there is no visible loading icon/screen and no error handling.
I'm not sure if there is an option to implement this already, but maybe we could make use of the Ember Loading and Error substates?
content-type is set to form-urlencoded
Accept:application/json, text/javascript, */*; q=0.01
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Content-Length:32
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Host:localhost:5000
Origin:http://localhost:5000
Pragma:no-cache
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36
X-Requested-With:XMLHttpRequest
I was reading through the LoginControllerMixin and found this ambiguous part:
if (!Ember.isEmpty(client_id)) {
postData.push('client_id=' + client_id);
if (!Ember.isEmpty(client_id)) {
postData.push('client_secret=' + client_secret);
}
}
Inside the first test for client_id being empty it is tested again.
Was the intention to check for client_secret being Empty?
Or am I missing something here?
reopen Ember.SimpleAuth.Session so that it also handles the authAccount
ember-simple-auth config:
App.initializer({
initialize: function(container, application) {
Ember.SimpleAuth.setup(container, application, {
loginRoute: 'user.login',
routeAfterLogin: '/user/dashboard',
routeAfterLogout: '/user/login',
serverTokenEndpoint: '/api/token',
});
}
});
The Test:
test("Visit login page", function() {
expect(1);
visit("/user/login");
andThen(function() {
ok(true);
});
});
The problem:
The test hangs during the route transition.
DEBUG: 'DEBUG: -------------------------------'
DEBUG: 'DEBUG: Ember : 1.2.0-beta.3'
DEBUG: 'DEBUG: Ember Data : 1.0.0-beta.2'
DEBUG: 'DEBUG: Handlebars : 1.1.2'
DEBUG: 'DEBUG: jQuery : 1.9.1'
DEBUG: 'DEBUG: -------------------------------'
INFO: 'generated -> route:user', Object{fullName: 'route:user'}
INFO: 'Rendering application with default view <appkit@view:toplevel::ember296>', Object{fullName: 'view:application'}
INFO: 'generated -> controller:user', Object{fullName: 'controller:user'}
INFO: 'Rendering user with default view <appkit@view:default::ember317>', Object{fullName: 'view:user'}
INFO: 'Rendering user.login with default view <appkit@view:default::ember329>', Object{fullName: 'view:user.login'}
LOG: 'Transitioned into 'user.login''
INFO: 'generated -> route:user', Object{fullName: 'route:user'}
INFO: 'Rendering application with default view <appkit@view:toplevel::ember398>', Object{fullName: 'view:application'}
INFO: 'generated -> controller:user', Object{fullName: 'controller:user'}
INFO: 'Rendering user with default view <appkit@view:default::ember416>', Object{fullName: 'view:user'}
INFO: 'Rendering user.login with default view <appkit@view:default::ember422>', Object{fullName: 'view:user.login'}
LOG: 'Transitioned into 'user.login''
LOG: 'Transitioned into 'user.login''
Hangs right here
The test will finish if I override the init function in simple-auth and strip out the body of that function. I think maybe there is an async call in init that isn't resolving or something?
Other than this test failing, ember-simple-auth is working as expected. All protected routes require login and the session object is being returned correctly.
FYI this is within an ember app kit project.
I think it might be more secure if the AJAX prefilter send the user identification (i.e. their email or username) along with the bearer token.
That way the server can look up the user both by email and access token, and seems to me like it would be more secure.
Hi,
I noticed in your list of "Middleware supporting RFC 6749", there is no mention of devise, the popular Rails Auth system by Plataformatec.
So i wanted to know if ember-simple-auth can work with that system as well?
Thanks!
API docs would be nice
Hey I love the work on this as I think it is such an important part of the Ember ecosystem. keep up the awesome work!
I am not a Rails guy and I am building an application using Ember-App-Kit. Any chance for an integration and usage example for EAK or at least for people who dont have (or perhaps want) rails installed in order to use it?
I assume in EAK I would just merge Core and Session into one file in the /app/helpers folder and then put the mixins under /app/mixins and then import the mixins where I will need to use them.
Any thoughts or suggestions?
I've setup the plugin and it works.
And I've the following Achievement
route which finds all the items from the rails server.
App.AchievementsRoute = Ember.Route.extend
model: -> App.Achievement.find()
Now, if I add the following to protect this route:
App.AchievementsRoute = Ember.Route.extend(Ember.SimpleAuth.AuthenticatedRouteMixin)
The data gets saved but the list is empty.
Does this mixin looks for something like current_user
kind of association?
The Achievement model in the rails side is user association free, it doesn't have any associations at all.
If I remove the Ember.SimpleAuth.AuthenticatedRouteMixin
, all the items show up.
Trying to setup with Ember app and as soon as I write:
Ember.Application.initializer
name: "authentication"
initialize: (container, application) ->
Ember.SimpleAuth.setup application
I get the error:
Uncaught TypeError: Cannot call method 'register' of undefined
Following is the console trace:
DEBUG: ------------------------------- ember.js?body=1:3231
DEBUG: Ember : 1.2.0 ember.js?body=1:3231
DEBUG: Handlebars : 1.1.2 ember.js?body=1:3231
DEBUG: jQuery : 1.10.2 ember.js?body=1:3231
DEBUG: ------------------------------- ember.js?body=1:3231
event.returnValue is deprecated. Please use the standard event.preventDefault() instead. jquery.js?body=1:5375
Uncaught TypeError: Cannot call method 'register' of undefined ember-simple-auth.js?body=1:52
Ember.SimpleAuth.setup ember-simple-auth.js?body=1:52
Ember.Application.initializer.initialize tagliners.js?body=1:5
(anonymous function) ember.js?body=1:36617
visit ember.js?body=1:35638
DAG.topsort ember.js?body=1:35692
Ember.Application.Ember.Namespace.extend.runInitializers ember.js?body=1:36614
Ember.Application.Ember.Namespace.extend._initialize ember.js?body=1:36499
Backburner.run ember.js?body=1:5716
Ember.run ember.js?body=1:6082
(anonymous function) ember.js?body=1:36364
fire jquery.js?body=1:3049
self.fireWith jquery.js?body=1:3161
jQuery.extend.ready jquery.js?body=1:434
completed jquery.js?body=1:105
I'm not sure if it's ember-simple-auth bug.
Let's say we have index route:
App.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('reports');
}
});
and 'reports' route has AuthenticatedRouteMixin
If we logout from 'reports' route it doesn't show login page - it still shows 'reports'.
When the user is logged in, the session lasts throughout the application even when refreshing the page. When the browser tab is closed, the session dies and does not continue when re-opening the page.
It also doesn't last if you open a link in a new tab/window - the sessions seems to be specific to that tab instance.
Is this intentional or a bug?
Hi, I'm using a modified version of this library in a phonegap application. Works fine. You might be interested to have this merged into the code base.
My hack involves moving the persistence to local storage when available.
If your interested I'l proceed with a PR.
A different approach might work be preferred : use cookies unless the protocol is file:// (or not http:// and not https://) and localStorage is available.
The difference is 'use cookies unless not http(s)' vs 'use localStorage unless not present'
What do you think?
How exactly do you go about testing this within an Ember app?
Is there a way to fake server calls, or just force it to log in with fake data?
Hi,
In the strategies branch, currently the way to handle login / logout link is:
{{#if session.isAuthenticated }}
<a href="#" {{ action 'invalidateSession' }}>Logout</a>
{{else}}
<a href="#" {{ action 'authenticateSession' }}>Login</a>
{{/if}}
However this seems like a bad approach and we should use {{#link-to}} because without using the link-to helper, we don't have anymore the automatic "active" class added.
more information here: http://stackoverflow.com/a/21004200/2527893
We've been having problems with unit tests. The test was fairly straight forward:
test("Login, render dashboard", function() {
expect(1);
visit("/user/login");
fillIn("#identification","test");
fillIn("#password","test");
click("#btnLogin");
andThen( function() {
equal(find(".island").length, 4, "Multiple islands should be rendered");
});
});
And the result in the console was:
Assertion failed: You have turned on testing mode, which disabled the run-loop's autorun. You will need to wrap any code with asynchronous side-effects in an Ember.run
In the debugger, we stepped through jQuery where it executes callbacks for AJAX responses. Eventually we found it. We needed to wrap your functionality with Ember.run() in your login function. This is around like 439 of ember-simple-auth.js in version 0.0.9.
Ember.run(function() {
_this.get('session').setup(response);
_this.send('loginSucceeded');
});
This has fixed the issue! Thought you should know.
Regards.
Hi,
Currently, Ember-Simple-Auth passes client_id and client_secret in post body. However, according to the spec (http://tools.ietf.org/html/rfc6749#section-2.3.1) this should be discouraged and we should use the Authorization header, using a base64 encoded string of "id:secret".
My backend expects 'Basic' and autoken requires some custom padding needs to be added and base64 endcoded.
Just an example
jqXHR.setRequestHeader('Authorization', 'Basic ' + btoa(session.get('authToken') + "padding"));
I looked at your ember simple auth examples, but I could not see anything documenting best practices for a sign-up user flow. Is there any documentation on recommended practices for a sign-up user flow?
simply check token type and add correct token accordingly
This looks like a great library! Can I make a suggestion?
I know the current token is based on an RFC spec that never made it.
I think it might be worth upgrading to an OAuth2.0 type authentication. It offers multiple grant types, one of which (Resource Owner Password Credentials Grant) is basically the same as what you have now.
The client sends their username and password and gets granted with an access token.
Its pretty much the same as what you have but follows a spec. It might save people time in the future as the chances are code is already available for their platform.
For example we use this excellent PHP library that has support built in already.
so implementing custom strategies gets easier; RFC 6749 would be default strategy
Hi,
I noticed in your list of "Middleware supporting RFC 6749", there is no mention of devise, the popular Rails Auth system by Plataformatec.
So i wanted to know if ember-simple-auth can work with that system as well?
Thanks!
Hi,
I've noticed that beforeModel
is not systematically called (manual URL change for example) and it would be better to trigger login from the willTransition
route action, wich is actually called for each transition.
Is that something you would aggree a PR for ?
I might be totally wrong here, but if I am then it would be nice if someone could explain the logic.
This line of code in Ember.SimpleAuth.LoginControllerMixin
is currently part of this:
if (!Ember.isEmpty(client_id)) {
postData.push('client_id=' + client_id);
if (!Ember.isEmpty(client_id)) {
postData.push('client_secret=' + client_secret);
}
}
Shouldn't it be this?
if (!Ember.isEmpty(client_id)) {
postData.push('client_id=' + client_id);
if (!Ember.isEmpty(client_secret)) {
postData.push('client_secret=' + client_secret);
}
}
It just seems a bit redundant to check client_id
twice and then not use it in the block, while at the same time just assume that client_secret
is present as long as client_id
is. Again, please enlighten me - I'm new to this.
Hi!
Is there a way to set all routes as authenticated ?
I've tried to add both Ember.SimpleAuth.ApplicationRouteMixin
and Ember.SimpleAuth.AuthenticatedRouteMixin
to my application route but there's an infinite loop to login page, which is itself authenticated...
Changing Ember.SimpleAuth.AuthenticatedRouteMixin#beforeModel
like this seems to work but I don't feel this to be robust enough:
beforeModel: function(transition) {
if (!this.get('session.isAuthenticated') && transition.targetName != 'login') {
transition.abort();
this.triggerLogin(transition);
}
},
these can serve as references:
probably also makes it possible to drop the ember-dev dependency
Hi there,
If you are storing auth token information in a cookie, I'm just wondering if this is strong enough to prevent CSRF.
Is this safe because the cookie alone does not allow authentication? (A client script needs to attach the token to a HTTP header)
It might be necessary to send the Authorization header cross-domain in some scenarios (when the data API is on a different domain than the one the page is loaded from). There should be the option to whitelist certain domains so that the Authorization header would also be included in requests to those.
There also seems to be a problem in the cross-domain case that might be caused by Ember.SimpleAuth: http://stackoverflow.com/questions/19755570/http-headers-setting-authorization-header-stops-data-from-loading/19773241#19773241
Hi,
I'm trying to use the new strategies branch, however I'm encountering an error:
TypeError: 'null' is not an object (evaluating 'this.get('authenticator').create')
It seems I've followed the example. As JS is not my primary language I'm not sure to be able to spot where the problem comes from.
Thanks!
How difficult is it to support this for Ember-Model? How about making it generic and can be used with any data drivers?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.