I have an Ember application that requires user authentication on the server side. Once authenticated (via login), application runs normally. The application shows a logout button. Pressing this logout button sends a message to the server, which causes the server to terminate the session, does some clean up, and sends the login page for the client to display. All this works fine.
But here's the problem: if the user hits the browser's 'back' button after logging off, he will see the app again and can interact with it. The app can still send messages to the server. Currently, the server will always respond by sending back the login page when the session is already terminated. How do I get ember to transition to this login page received from the server? The fact that users can still get back to a running application (at least on the client side) after logging off would cause some confusion.
What's the recommended method for handling this? Is there anyway to make the Ember application end when the user hits the logout button? Maybe just disable the browser's back button when the user logs off (how do you do this in Ember?)?
You can either check in every route if the session is loggedIn or not in activate hook of route like this..
if you are setting a variable loggedIn true here is how to do it.
App.PostRoute = Ember.Route.extend({
activate: function() {
if (!loggedIn){
this.tansitionTo('login');
}
}
});
If you want to remove totally PostRoute from history you can use replaceWith rather transitionTo.
.or use these for authentication ember-auth or simple-auth
Related
In a Home page, i have a form login. in the view.index of the app "Home", after authenticate, i create the ssesion. And after, i call the app "Places" if the authenticate is okey,
request.session['user'] = username
request.session.set_expiry(900)
return HttpResponseRedirect('/places/')
in the settings of the project i configure the SESSION_SAVE_EVERY_REQUEST = True.
How can i send the session to all others pages of the project, and log out the user when the session is expired ?
HTTP is a request response protocol.
This means that the server has no way to to communicate to the client without the client initiating the conversation. So the only way to do something like this is native Django, is to have the client periodically check to see if the session is still ok.
One way to achieve this is with a background ajax call (perhaps using setInterval in javascript) which checks the session, and if it's not any good anymore (either by expiration or the user has been disabled etc) then redirect them back to the login page.
Another approaches could involve sending the expiry time to the client so that it only checks the session when it would have expired (though this wouldn't pick up on users being disabled) or having a websocket server which pushes this information to the client.
I have an app where on initial load the user is redirected to sign in page. Once the user is authenticated, he is then taken to homepage. While verifying the user, an HttpOnly cookie is also set to the browser. So now to remove the hassle for user to login every time he refreshes the app or opens it in another tab. I'm sending a authenticate request back to the server inside beforeModel hook of my application route. This will verify the user and page loads as expected. However if the server response has 401 (either because user logged out or cookie expired) the app will redirect him to login page. Everything works fine and as expected.
But there are few things tricky to resolve.
If the user gives path as /login I need to wait for the authenticate request to complete before deciding on to render the login template or to redirect to home screen if he is already logged in.
Also wait for validate call to complete before executing the model hook in target url. I saw the modal request going to server even when the response was 401 for authenticate call.
A good example is in github page, where once you log in and go to /login page they take you to your home page.
After some experiment with routes.
I came up with this solution.
On every url request( either by refresh or entered path ), store the url unless it is for /login. This would be done in most likely beforeModel hook of application route.
Then on each topmost route of route hierarchy that an authenticated user can browse through have it redirect to login route.
On login route make the appropriate call to the API for authentication. If user is logged in transition to the stored url or to homepage if nothing is stored. If however 401 comes back load the template for the same.
Make sure that your async call for the API is made in one of beforeModel, model or afterModel hook, and you have the call to API in a return statment, otherwise the template will load no matter.
NOTE:
1. You can have the url stored in some service which will be accessible throughout app. You can also have the service store other login information for future use.
2. In point (2), make sure to do some check before redirecting to /login in case of unnecessary redirection. Suppose if the route was transitioned internally rather than through page load. 3. Don't forget to handle 401 case in your authenticate request, or it may just display nothing on page with an error in console.
Hope this helps
The page to login to our application is a jsp hosted on another machine. I have managed to get requests firing to this machine by modifying authenticated-route-mixin by allowing window.location.replace to be called if the route start with http.
beforeModel(transition) {
if (!this.get('session.isAuthenticated')) {
Ember.assert('The route configured as Configuration.authenticationRoute cannot implement the AuthenticatedRouteMixin mixin as that leads to an infinite transitioning loop!', this.get('routeName') !== Configuration.authenticationRoute);
transition.abort();
this.set('session.attemptedTransition', transition);
debugger;
if (Configuration.authenticationRoute.startsWith('http')) {
window.location.replace(Configuration.authenticationRoute);
} else {
this.transitionTo(Configuration.authenticationRoute);
}
} else {
return this._super(...arguments);
}
}
This is working but when I am redirected back to my application, ember-simple-auth thinks I am no longer logged in and redirects be back to the remote machine, which then sends me back to the application in an infinite loop.
Obviously I need to set something to let ember-simple-auth know that it it is actually logged in. Why is it not doing this automatically? What am I doing wrong?
I am pretty new to oAuth so I could be missing some basic setting here.
Here is the URL.
ENV['ember-simple-auth'] = {
authenticationRoute: 'https://our-server.com/opensso/oauth2/authorize?client_id=test-client-1&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A4200%2Fsecure'
};
Instead of modifying the AuthenticatedRouteMixin, I'd recommend handling your app-specific login in an Authenticator-- the key configuration primitive that Ember Simple Auth provides as part of its public API.
To the best of my understanding, on first loading the app, and checking to see if a user is authenticated, Ember Simple Auth will use the restore method, defined as part of the Authenticator API.
You can return a promise from restore that resolves or rejects to indicate whether the user is authenticated. How you check this is an implementation detail of your auth system.
I don't know how you're storing credential(s) on the client (would be great if you could provide more detail), but here's an example flow, using cookies for authentication:
Ember boots, ESA attempts to restore the session.
restore makes a simple AJAX request to a secured, "dummy" resource on your Java server-- and checks if it gets back a 200 or a 401.
We get a 401 back. The user isn't authenticated, so reject in the Promise returned from restore.
Let ESA redirect the user to your authentication route. Ideally, don't override the AuthenticatedRouteMixin-- instead, use the beforeModel hook in the authentication route to send users to your JSP login page.
The user correctly authenticates against the JSP form.
In its response, your Java server sets some kind of encrypted, signed session cookie (this is how it generally works with Rails) as a credential. In addition, it sends a redirect back to your Ember app.
Ember boots again, ESA calls restore again.
restore pings your Java server again, gets a 200 back (thanks to the cookie), and thus resolves its Promise.
ESA learns that the user's authenticated, and redirects to the 'route after authentication'.
Keep in mind that, at its core, ESA can only indicate to the client whether the backend considers it 'authenticated' or not. ESA can never be used to deny access to a resource-- only to show something different on the client, based on the last thing it heard from the backend.
Let me know if any of that was helpful.
I have an Ember app using Ember Simple Auth. I need to revoke tokens on the server side, which I can do easy enough by setting the revoked_at column, in the oauth_access_tokens table, to a timestamp.
This causes the server to respond to Ember with a 401, which is great. However, Ember Simple Auth does not seem to fire the authorizationFailed action in the application route. I put a simple debugger in the action to test if it's getting hit.
What I want to happen is trigger any kind of authorization error to hit this action, which would allow me to manually run invalidate() if it hasn't done so yet, and redirect them to a login page.
Thanks.
I'm using ember-simple-auth for my Ember app, but I don't have an API endpoint to authenticate users, rather it does a page redirect to the form and signs a user in, then redirects back to my app. (I don't own the authentication)
After authentication, it gets redirected back to me, so I know on the server side when a user has been successfully authenticated. How do I manually authenticate the users' session when they are redirected back to my app?
Currently I did a hack to write two cookies: ember_simple_auth:access_token and ember_simple_auth:authenticator.
I think setting up the session store manually is an ok solution in this scenario as that will trigger the session to be restored after the redirect (which is on startup of the Ember application). I'd maybe configure a custom authenticator that redirects to the external login page in the authenticate method. That way you have that redirect centralized and it will also be triggered automatically whenever Ember Simple Auth automatically enforces session authentication (e.g. from the AuthenticatedRouteMixin).