fenichelar/ember-simple-auth-token

[feature] Authenticate with JWT passed through response cookie.

hoIIer opened this issue · 5 comments

Greetings, I'm investigating passing the jwt in the auth response as a samesite httponly cookie instead of returning it in the json payload as this library expects.

Has anyone attempted to use this package in such a way, or would anyone else be interested in using an authenticator that expects the jwt to be in a cookie and not the response body? I can help write it but I wanted to gather feedback to see if that even makes sense to add... cheers

If you have comments on the topic feel free to share!

An httponly cookie is not accessible by this library or even Ember because it is not accessible via JavaScript. So you can't use an httponly cookie to pass the JWT to the client side application.

You could use an httponly cookie without ever passing it to the client side library, but in that case, I'm not sure you would use this library at all.

You could use a cookie without httponly. But without httponly, I'm not sure you would want to use a cookie to store the JWT. You would loose all of the XSS benefits httponly cookies have, and you would now have to deal with CSRF attacks. You can limit cookies to HTTPS only (secure flag) which you can't do with local storage or session storage, but I'm still not sure that is worth the CSRF attacks.

Regardless, it should be fairly easy to use this library with cookies. You would just need to overwrite the handleAuthResponse to have it look at the cookie instead of the response body. And then you would just not use the mixin because the cookie would always be sent to the server without having to do anything special.

@fenichelar curious for your thoughts on the optimal way to handle it. From what I gather, the optimal and most secure way is to use an httponly cookie and not return the jwt in the response body. But yes this library seems designed specifically for returning the jwt in the response body unless I have something mistaken. In my app I overload the local session by adding some bits of info to session.data, e.g. "isVerified: true". Just curious if you have any thoughts on architecting a secure login with this or other libs.

@burritoIand

the optimal and most secure way is to use an httponly cookie

I don't agree with the above statement. Using httponly cookies and localstorage are different. They can both be implemented securely and they can both be implemented in insecurely.

This library is specifically designed for returning the jwt in the response body because if you are using httponly cookies, then you don't need any of the functionality in this library. An httponly cookie is by design not accessible by JavaScript, which includes ember, ember-simple-auth, and ember-simple-auth-token. When using httponly cookies, you basically just need to make the API request and if you get a 401/403/etc. error, redirect to a login page that when submitted makes a request to the server login endpoint which sets the cookie. There isn't much logic needed client side.

In summary, there isn't an optimal way of handling authentication. The various authentication designs have pros and cons that need to be considered for your specific use case. And all authentication designs have security pitfalls (XSS, CSRF, etc.) that you need to be mindful to avoid.

If you plan to use localstorage, then this library handles a lot of the logic for you. If you plan to use httponly cookies, then I can't think of any reason to use this library.

@fenichelar thank you for the response, it makes sense now. The one thing I wasn't sure of is how to store extra session data if you're using the cookie method, but I guess you'd store it as either a second non-httponly cookie or create an entry in localstorage.

Right now I'm stuffing a small number of extra boolean flags into session.data (e.g. "didUserConfirmPasswordThisSession")

@burritoIand Yes, you would need to store the session data separately. Localstorage generally makes more sense for session data because using cookies will increase the size of the requests to the server. If the server doesn't need the data, then there is no point in sending it with every request.

You could synchronize the data between localstorage and session.data or just directly use localstorage.