What is Stored in Stateless JSON Web Tokens - javascript

I have been reading up on JWT recently, and feel I have a pretty decent grasp of how they are made and how the could be used for authentication.
If I understand correctly, a challenge with stateful applications occur when I need several web services (APIs), one for each type of device using the app (web, mobile, etc.). Then, the web services must somehow synchronize the session states, which is hard.
Instead, we store state client-side (preferably in cookies) within encrypted and signed JWTs.
Have I understood it correctly so far?
Then, my main question: What exactly is stored in the JWT, for let's say an online store? Does it completely replace all user info stored in a database? So, profile information, images, shopping cart, saved content (articles, repos, etc. if applicable), and more. Is all this, and all other imaginable content differing from one user to the next, saved inside the JWT?
In conclusion, I am trying to get at what is meant by stateless in JWT use cases? Do we store all user info in the token?

[..] when I need several web services (APIs), one for each type of device using the app (web, mobile, etc.).
I would argue that it's bad architecture to separate your server backend by the type of client. Ideally the backend will offer the exact same API to web clients and mobile clients (and any other clients). Otherwise you have a huge duplication and overhead for every supported feature.
So instead, let's just concentrate generically on the case where you have several servers. Any serious large scale web site, think Amazon.com, has way more than a single server serving their web site. They have individual server instances coming online automatically as demand increases and dropping back offline as traffic ebbs. Load balancers direct traffic to individual servers as necessary.
In that kind of scenario, especially with a shopping site, you have several ways to handle state then, each of which has certain pros and cons:
Use sticky sessions, which means web servers are stateful and store session information, and the load balancer is aware of the used cookies and will direct traffic from the same client to the same server so only one server needs to hold on to the session info. This makes the server implementation relatively simple, but has certain drawbacks in operation:
The load balancer needs to be able to handle sticky sessions.
The server needs to stay online while the client exists, otherwise the session information is discarded.
If the client moves geographically to another load balancer, they may get disconnected from their session.
Use a shared session storage backend, so each server essentially shares the same information. That negates the drawbacks from using sticky sessions, but obviously re-introduces the bottleneck of a single shared resource and impacts scalability. That can be mitigated to some extent by using good caching strategies, but writing to shared storage still requires an enormous backend.
Keep everything stateless and handle as much as possible on the client itself. The client remembers its own history and/or basket contents. All the server needs to do is provide the product information, which is non-client specific and therefore extremely scalable. Of course, when it comes time to checkout or do other client-specific things, the server will need to do client-specific actions and use a session of some sort or another, but that is just a fraction of the traffic compared to casual browsing and much less of a problem.
In this kind of scenario, JWTs serve to carry information which needs to be validated, like who a user is, i.e. authentication. For authentication purposes, you can either:
Have the client authenticate themselves with every request, i.e. send their username and password with every request. That is obviously a bad idea, since you don't want to send the password back and forth constantly. It would also require a query to a central database on the backend each and every time, which undermines scalability again.
Give the user a token of some sort which authenticates them. The drawback here is that is requires a shared token store, see #2 above.
JWTs let you have it both ways: the user essentially claims on every request that they're user X (without sending their password), and because the JWT is signed by the server, it allows the server to actually trust that claim. Each server can verify the signature independently, and hence trust the claim independently on each request, and thus remain stateless and also not require any sort of shared storage.
A drawback of storing information in JWTs is that they only exist on one client, so any information you store there ceases to exist once the user moves to another client or clears cookies; so synchronising a shopping basket between devices for a user account is not possible with just JWTs alone.
In practice, you'll probably use at least two, probably all three approaches together. You'll have some shared storage somewhere to store account information (including the shopping basket), but you reduce the need to contact that storage as much as possible by also caching that data in sticky sessions and/or JWTs. Stateless authentication via JWTs is something of a no-brainer. For everything else, you decide on the right tradeoff between imparting load on a shared storage, how up-to-date any shared/cached state will be, and the end user experience.

Related

How to detect another session is ongoing from another browser tab using Parse Server error

I'm trying to auto logout an app if user logged in from another tab or browser.
I'm using react-idle-timer and Parse Server.
I'm not sure if this line of code will be useful
Parse.Error.INVALID_SESSION_TOKEN
I can access session token via localStorage
const res = await Parse.Cloud.run('login', values);
console.log(res.session);
You can't differentiate a request from a different tab within the same browser. It will share the same session token and be indistinguishable from any other request. Requests made from different browsers will have different session tokens and if they store some user info you can determine which ones belong to which user.
If we reframe your question it sounds like you only want to allow for one active login per user. This requires a centralized or clustered session management solution that supports preventing multiple concurrent sessions.
If you will only ever have one backend server or you are using a shared database to store sessions, then you can do this a bit easier depending on what you are using for session management since all sessions will be available on the one server.
It is not clear to me if your users are connecting directly to parse server. If they are you will most likely need to modify parse-servers code directly to support this.
In general this is a silly idea. Unless you have a legal requirement to do so I would not advocate worrying about this. Bypassing this is usually as easy as copying around a session token.

Is it a secure way to handle returning user in ember?

I am using ember to write a web ui for a site that requires user to log in. Suppose the browser has stored some cookie from last login of a user. Now the user visits the site again. So, is it a secure and common way for ember to log the user in automatically based on the cookie from the last visit? If so, what are the common ways to implement this? (I can't find anything from Google.) Furthermore, how do I create the cookie upon login? Is it a common way to just put a user id, password hash, and expiration in the cookie?
Additionally, any references related to this subject are greatly appreciated.
Edit 1
In light of Vohuman's answer, I think I can make my question a little more specific. Basically, what I want to know is a common and secure implementation to keep a user logged in, even when they close and reopen the browser. Namely, the life time is beyond the session scope. Take linkedin for example. If you are logged in and exit the browser. Then next time you revisit linkedin, you are still logged in automatically. Right now, what I can picture is a solution like the following.
When you first log in to the site, the server will return a cookie which includes an authentication hash token. Then next time when you revisit the site, the server will receive the hash token and thus authenticate your session.
So, is above flow basically what people usually do to keep a user logged in? If so, is the JSON Web Token (JWT) basically one way to construct the hash token I mentioned above? Additionally, assuming the connection is HTTPS, this approach seems secure to me. Is it not?
Edit 2
This article gives an interesting discussion regarding where to store the access token.
is it a secure and common way for ember to log the user in automatically based on the cookie from the last visit?
Yes and no. Security is a complex topic. Usually session cookies are used for authorizing users. This is actually the most used method of keeping the users logged in. If the user can't keep his credentials secure then any layers of security can be vulnerable.
For Single-page applications usually access tokens are used instead of cookies and sessions. The client sends the user credentials and server returns an access token. The token is encrypted and expirable and can be stored in localStorage or sessionStorage. Using JSON Web Tokens (JWT) standard is a popular method for implementing user authentication and authorization in web services. As an example, the Facebook Open Graph API uses access tokens.
JSON Web Token (JWT) is a compact, URL-safe means of representing
claims to be transferred between two parties. The claims in a JWT
are encoded as a JSON object that is used as the payload of a JSON
Web Signature (JWS) structure or as the plaintext of a JSON Web
Encryption (JWE) structure, enabling the claims to be digitally
signed or integrity protected with a Message Authentication Code
(MAC) and/or encrypted.
edit:
So, is above flow basically what people usually do to keep a user logged in?
For traditional websites, yes.
The whole point of using access tokens is keeping the web service/API stateless. This means that server doesn't have to store any cookies/sessions for authenticating and authorizing users. The stateless is one of the key factors of implementing web services that follow the REST paradigm. It's client that has to store the token and send it to the server (via the Authorization header or query parameters). The server doesn't store the token. Of course, you can store the tokens on the server if you want to add another layer of security, but it's not so common and not necessary. Storing the tokens on the server can also make your application vulnerable to database attacks and is not recommended.
If you want to make the process more secure you can decrease the validity time of access tokens (1 hour, 1 day or 1 week, it's up to you).
As for localStorage, is it secure?
localStorage data are stored separately for each origin (domain). A malicious user can only read the data if he/she has access to the user browser. You should make sure that your app doesn't have any XSS vulnerabilities so malicious users can't inject any scripts to your application. This is actually a different topic.

Asp.net web api Session

I'm not getting the concept web api and session.
I've created asp.net web api project and integrated angularjs in it.Every time I'm gonna call web api.
I have read the articles which state its not good to use session in Web api. I do understand that web api is stateless approach. I do agree. stil there is a way to use session.
First question: If, after login, i want to show user name on every page what should i do with web api approach????
second question: they say don't use session in webapi. then what is the other way/approach to store client information safely.
If I use HTML5 local storage, it can be editable.
If cookie is used, it can be deleted.
What and how should I do it for user till application is in running mode?
This is where semantics often clouds the discussion. People confuse the Session object with statelessness. And often say: 'don't use session because it isn't stateless!'.
However they really mean that you should strive to have your the restful calls to be idempotent, meaning they don't change their behavior depending on whatever it is you do in the background.
Session, or the runtime-cache, or whatever it is you use to cache data, has no effect on your stateless design, because really, what's next? Your database is statefull too? And you shouldn't read data from that? Nonsense obviously; your underlying storage, if it's in-memory or on disk has no reflection on your state to the client.
Although I feel #MajoB makes other valid points about not using the session object, there is really no harm using some kind of cache in the web api, session or something else. But never let the fact if something is IN session return a different result then when something is OUT of session.
I would recommend you to avoid asp.session because it may cause performance issues and can expire anytime regardless of your application state, does not scale on cloud, it will block concurrent ajax requests). Better approach would be to use HTML 5 storage mechanism especially in conjunction with AngularJs (you can use ng-storage https://github.com/gsklee/ngStorage).
I would recommend you use asp.net identity and render user information on server.

Where is best place to store authorization data when I use Backbone and AMD modules?

I create js app with Backbone and RequireJS for registred or non registred users. To retrive data from database I use simple JSON web service and of course some of methods are not avaiable for quest. Problem is that I don't know where or how I should store auth data retrive from server without reloading it in every view. Should I use cookies ?
I guess it depends on your authentication, authorization methods as well as the kind of security you need to consider for your users. If you're trying to be RESTful, you can't have sessions to save state (at least server-side). You could, but it wouldn't be RESTful due to saving of state on the server, if that matters to you. I've heard that it is okay to save state client-side but from what I've read, I'm not sure how the community feels about certain implementations that take this approach. (Like cookies, I'll revisit this later.)
Say you have someone login with username and password. You can hold that information in your Backbone app, maybe you have a model called AUTH that does this. Each time you make a request to the server you'd send that data each trip at which point the server authenticates and gives or rejects access to given resources. If you use Basic Auth this information would be in the header I think. Using SSL mitigates some of the major security concerns surrounding the sending of this information over the wire and for the rest of the discussion let's assume this is what we are using.
The other way that you could do this is to use encrypted cookie, encrypted cookie sessions. This is what I do with my current application. Honestly, I don't know if this is considered a violation of RESTful principles or not. The general chatter on the web seems to be a lot of "cookies bad, sessions bad" with some people saying, "get real." Using cookies would expose you to cookie hijacking if someone had access to the users computer, but depending on your application and the security needs it might not be an unreasonable option. It works for me and if it isn't RESTful, I like to call it RESTLike.
To close I'll just describe my setup. It would be nice to get your thoughts as well as the Stack's opinions on this also.
Basically I have a setup where when someone goes to the main page, the server checks for the encrypted cookie session. If the cookie session is invalid or non-existent, it gives the user the regular page with a chance to login. When they login, I send that information over POST so it's in the body of the request rather than the URI. (This is technically a violation of the REST HTTP verb concept since you use POST to save a resource.) When that information is processed, check the username, pass hash created by a unique salt, then the server creates an encrypted session cookie and passes it back to the user. Now, each time my user hits a route that requires authentication, the server checks the cookie to make sure it is still valid (time limit, user information, etc.) and if so - allows access. If not, it destroys the cookie information and sends back an appropriate status code. The backbone app reacts to this by resetting any view and data that shouldn't be in the hands of an unauthenticated user and shows them the login screen.
Hope this gives you an idea. This is the answer to how I do it, but if someone has criticisms or better ideas I'd be happy to upvote them instead.

User authentication in offline web apps

I'm building a web app that needs to work offline. The system is built to capture sales transactions. The bulk of the "offline" part is fairly straightforward -- I just need to store data locally and sync it when I'm back on the network. So far, so good.
The problem is with authentication. The app will run on a shared machine with a single OS user account. If I'm offline, how do I authenticate the user?
Users themselves do not have any private data that I will need to segregate (i.e., I don't have to protect them from each other on the client). I need to be able to validate their password so I can let different users login throughout the day even if the connection is down.
One approach I'm thinking of involves caching the password hashes on the client-side in an IndexedDB. Only a limited set of users will be allowed to log in from a specific shared machine, so I won't need to cache my whole password database locally. Assuming that I have a good password policy (complexity and expiry requirements) in place and the hashes themselves are secure (bcrypt), just how horrible of an idea is this?
Do I have any other options?
This is effectively how Windows (and other systems) work when the machine is not able to reach the domain controller (e.g., you take your work laptop onto the airplane and need to log into your laptop w/o connectivity). Your machine has written down a cache of your username|password pair and will let you in via those credentials even if it's offline.
I think generally speaking storing the username|password hashes is pretty safe, assuming you're hashing them reasonably (e.g., using a salt, using an IV, etc). One exposure you'll want to think through is having the hash file "escape." If this is sensitive data you'll want to be exceedingly careful -- and this may not even be acceptable, but if it's not super sensitive data then you're probably OK: with good hashing I think you should be reasonably (but certainly not completely) safe.
Maybe this is little unrelated, but I use this approach in my nodejs project.
When a user is authenticated by username and password, he/she is assigned a unique API key used only for this particular session.
Each user can have only one API key.
This API key is added to any request done to server, to authenticate the user.
When the user logs out, the API key is deleted. Also the API key can be purged on the server, that makes the user authenticate on the server one more time.
I can provide links to nodejs open source programs that use this approach if you interested.

Categories

Resources