Ember Simple Auth when all pages requires authorization - ember.js

I have website that requires authorization on all its pages. To achieve that there is server that response based on cookie. If there is cookie send ember app, login site otherwise. This allows to facebook like behavior. I am using ember-simple-auth addon to help with authorization.
Since user is never inside app without being successfully authorized, one should be able to save ember-data record object into session. This works nice for one tab but breaks horrible with multiple tabs. Is there way how to have ember-data objects in session and yet support multiple browser tabs?
Edit:
I maybe found workaround, save index into session and use peekRecord in computed property.

Related

JWT Authentication with Rails and Ember JS

What is the right way to proceed the logout action of the User when using JWT, Rails API and a JS front-end framework, for example Ember JS ? What I'm actually doing is:
use Rails 5.2 as API
use Ember JS 3.3 as front-end
use Ember Simple Auth as OAuth add-on
example app, its master branch, works as needed
example app, its without login branch fails to logout the User
check the presence and pass in a token in every request between Rails API and Ember JS apps.
The questions I have are:
Should I keep a token value in the backend model (User, for example) ?
I need it to make another request in the background on the backend side.
Should I set the token value to nil when the User logs out in the backend ?
What am I doing wrong with ESA as for logout action ?
Actually the token value is kept in a cookie on the client side (see https://github.com/simplabs/ember-simple-auth for more details). I followed their guides and the dummy app they provide.
I also had a discussion on Ember JS Forum and tried to follow some tips and advises, still no success.
Thank you.
This answer applies to Ember 1.13 through at least 3.x.
Authentication comes in so many flavors that I think the right way to do it is whatever is an easy-to-understand fit with the back end.
Since your JWT is in a cookie, let's think of that cookie as the source of truth. Rather than doing something complicated to parse the cookie in a model hook, you could define a Service that has functions to grab the cookie, parse it, and either save the results to values on the service or return the values you need.
This gets you a few benefits. You can get the values from anywhere in your app, including adapters, and all the logic for auth lives in once place. On the other hand, you would have to handle async behavior yourself (i.e. if a route depends on having login info, you will have to manage the order of operations between authentication and route transitions).
Ember Simple Auth is quite popular because of this issue. Although there aren't out of the box features for JWTs in cookies, if you have an app with different states based on logged-in behavior, it might be a good investment to learn it.
The user model is kind of a middle ground between a hand-rolled service and Ember Simple Auth, since you can get the user model and rely on it throughout your app, plus get a little help with async. Just be careful not to scatter your auth code across your whole app.
Lastly, to trigger logout, I would create a function that destroys the cookie by setting the max age/expiration like this. If you are handling auth on a service, this means you could use Router Service and then transitionTo a login page. If you are using Ember Simple Auth, that functionality can go in the invalidate hook of your custom authenticator. Example:
invalidate() {
this._super()
document.cookie = "some_token_name=; expires=Thu, 18 Dec 2013 12:00:00 UTC; path=/"
return Promise.resolve();
}
Lastly, for passing the token to authenticate requests, if you are using Ember Data, this can be done easily in the adapter's headers method.

Understanding SessionAuthentication in django-rest-framework?

I am using Django v1.8 and django-rest-framework v3.2.2. I have a site with a public-facing API, which is also consumed by my own site (on the same domain) as the Ajax back-end to a JavaScript application, using GET only.
I want public users of this API to be asked for a key parameter in the URL, which I will issue manually. But I also want my JavaScript application to be able to use the API, in a way that means that other users can't just steal the key and use it.
I have set up my custom key authentication as described here, and it's working well.
However, I'm unclear on how the JavaScript application should use the API. Obviously I could just pass a dedicated key parameter in the URL, but then won't other users trivially be able to spot the key and use it?
I think I need SessionAuthentication, but how do I even start to make this work? I can't see any instructions in the DRF documentation about how I need to change my JavaScript calls to use it.
Also I don't understand how SessionAuthentication allows the Ajax app to authenticate without other users being able to see and copy the authentication.
Very grateful for any advice.
I think I need SessionAuthentication, but how do I even start to make this work? I can't see any instructions in the DRF documentation about how I need to change my JavaScript calls to use it.
SessionAuthentication is the Django's one. It uses session to authenticate a user. It's mostly transparent for ajax request as the browser will send the cookie automatically. However, if you're posting data, you need to make sure you send the CSRF token in both headers and post body.
Also I don't understand how SessionAuthentication allows the Ajax app to authenticate without other users being able to see and copy the authentication.
As said above, it uses cookies for that. They are part of the headers and thus usually not seen on the urls.
To make sure no-one else can steal user's session you need to run the site through https.
This isn't much different from regular websites.

Authenticate Facebook users in Cakephp 3x

I have used PHP SDK-4 for Facebook login in CakePHP 3 (beta version) which works fine.Now, I'm in need to fetch user data based on FB login and authenticate users. Am trying with Cake's Auth component. Initially, while trying to Auth users,
$this->Auth->setUser($user)
Got Error: Session was already started as we require session_start() for Facebook login. 1- Tried with enter link description here, and sessions [session_write_close()] etc..still it did not work. Could I get some shot on best way to authenticate users with Facebook login in site?
CakePHPs sessions are lazy started, that is, they are being started once your try to access the session in some way, and in case the session was started manually in beforehand, you'll receive that error, see Session::start().
You can easily workaround this by manually starting the session via CakePHP. The session object is available in the current request, so for example in your controller before using the SDK you could simply do something like
$this->request->session()->start();
and then the Facebook SDK should be able to pick it up.
As burzum already mentioned in the comments, the authentication should better be wrapped up in an authentication handler.
I would suggest having a look at HybridAuth, there's also a CakePHP plugin for seamless integration into CakePHPs auth mechanism, this might give you some ideas for a custom implemenation in case you need to use the v4 SDK, which isn't yet supported by HybridAuth.

Twitter OAuth and WebApp (with Ember)

Currently I am working on an WebApp with Ember.JS. Now I want my customers to log in with their Twitter account using OAuth but I don't want my App to reload when they do.
So my idea was to have the login button open an popup to the Twitter authentication page which redirects to my page which has some JS based on the result e.g
window.opener.success(userdata);
and
window.opener.failure(error);
But since it first redirects to Twitter (the popup) browsers remove the window.opener properties to prevent cross site scripting even though it does redirect back to my own domain (where the JS code is).
Is there another way to go about this?
edit: I could user postMessage, but this doesn't work in IE8/IE9 in a popup. Only in an iFrame.
Yes, you have the same idea as some other programmers at Vestorly; they made a social authentication plugin called Torii I would recommend this as they have probably also taken care of all your obvious security concerns.

Django CSRF protection for mobile apps and chrome extensions

I have done a few mobile apps using django as my backend, and now I am working on a chrome extension. I want my users to be able to send POST requests up to the server using the app/extension but is there a way to do it without first asking the server for a CSRF token? It just saves the app from making two requests every time we want to submit data. For example, I want to update my profile on my social media app or update a wallet from a chrome extension. It would be nice to open up the profile view input the data and push it to the server. It's less sleek if I have to open the profile, then wait for it to grab a token from the server and then I can submit the data. Is there another way to do this? Or am I stuck making multiple requests every time I want to submit data?
Also, a little clarification, CSRF prevents sites from submitting forms with user's data. But what is to stop me from making a site that uses ajax or something to grab the real site and steal the CSRF token and then paste that into my cross site request form? I feel like there is a loophole here. I know that I am not quite understanding this all the way.
You can, and should, make any API endpoint CSRF exempt.
Django offers the csrf_exempt decorator for exactly this, see https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#django.views.decorators.csrf.csrf_exempt.
Also CSRF is intended to prevent unintended actions being performed via GET request forgeries. It is not intended to make it impossible for an automated system to submit forms, there are captchas for that.
As for what prevents you from using AJAX to grab the whole site and extract the token is something called the Same-Origin Policy. This is implemented by the browser and prevents any AJAX call from returning data when the target of the AJAX call is a different domain without the correct headers set. (I'm not entirely sure what sandboxing is applied to chrome extensions concerning this). As such it will, or at least should, fail to get data via AJAX for normal websites, e.g. a profile page. If you want to interact with third party websites you should look into whether or not they offer an API.