I‘m developing an adminpage with login functionality using Node.js, react and Redux.
For the login I used jwt. My question is, is it safe to use this? Because, i set Provider with the store around my App. And Inside i check if the user.isauthenticated() then adminpage Else loginpage.
What worries me is the store. It is the same store in the loginpage and in the adminpage. So I have access from the login page to the store which is connected to the adminpage.
Would not it be safer to have two separate stores?
Nothing on the front end is “safe”. The real question is how you handle authentication/authorization in your backend. JWT is definitely a secure method for authentication, but keep in mind that the payload can be decoded by anyone, so any information stored in a JWT is visible to anyone who can access the token.
The safety consideration is this: could a user authenticate using your front end service, then use that token to access information from your backend that does not in some way belong to them? If you’ve built your backend properly, then your front end stores won’t be able to leak any information, because they won’t be able to obtain any information the user wasn’t already authorized to view/edit.
One scenario to keep in mind with front end security:
A user logs in, and proprietary data is stored by your front end app (whether redux/localstorage/etc). When that user logs out, if that data remains in the store, could another user log in and then view it somehow? Hopefully not. Your logout methods should remove any sensitive data from that frontend app, so any future user won’t have access to it.
I hope that helps. I might not have addressed redux directly, but that is because security is primarily a backend concern. Redux shouldn’t be relied upon to keep data safe, unless it is deleting stuff permanently from areas that unauthorized users could access later.
Related
So I'm working on a react application as a front and as the back python, Django and rest.
I'll do the front part in a few days, but a question spawn: how can I manage all my apps for the user with an account and the other (without the account)?
I look a few options but I don't really know which one is better:
local storage
context API
cookies
For example if the user is connected and wants to see him own profile page, he could without fetch in the code cause it's just a few information like name, email, ...
I don't know if it's enough to clear but hopefully enough to get some suggestions.
Cookies are mainly for reading server-side, whereas local storage can only be read by the client-side.
An other point is saving data, a big technical difference is the size of data you can store, localStorage give you more space.
Context API you'll use it eather you work with cookies or localStorage
You can call the API for fetching information the first time the user logs in, and then you could store the information on the app state for the whole session. If you want to store information between sessions localstorage works just fine, is easy to access. However, you'll have to check if this information exists when the user logs in.
Context API can help you to access the stored data easily by using useContext react hook API in other child components and manage them by React, but localStorage is a way to persists Context API changes with localStorage to get them back after every page reloads(prevent losing data in page refresh). But cookies have a maximum length(I don't know how much is it) which isn't the best way because it has security issues and a use-case of cookies is using them on the server-side by the backend.
Currently I'm working with -
Django REST Framework
Angular 5
RxJS +
OAuth2
The list of paths of all components except the LoginComponent I have AuthGuard where I check whether the data on the token and the user in the localstorage of the browser.
If data is available I will return True. But as soon as the token expires, I can't do anything with the user.
If I get a 401 code in the service, I can't even redirect the user to the login page since I can't use the router in service.
Basically I am wondering how, when and where to update the token in my web app?
Kindly give some knowledge on how to work with tokens. Also it would be helpful if any code example is provided.
You question is too broad, and opinion-based. But if you want a thrid party point of view, here are my two cents :
Storing the Token
Depending on your application, you have several ways of storing a Token.
LocalStorage
The first solution, the one you used, is storing it in the local storage. This way, the Token will remain on the device as long as you (or the user) doesn't delete it.
Session storage
The session storage will behave same as local storage, except that the token will be deleted once the user closes his session.
Service storage
Last option : storing it in a service : your token will remain as long as your user stays in the scope of Angular (meaning, doesn't reload or change tab).
How to chose ?
Depends on your application. If you make an application involving high risks after login, then you should consider using the session storage, so that the user gets "removed" as soon as he leaves the page. For a casual application, stay on the local storage. And if you REALLY want to lock your application up, use the service storage.
When to store the Token
Seems obvious, but you should store it when the user logs in.
Update the Token
You should not have to do that. The Token matches an user, or an user session. The only update you should do is a deletion, not a rewrite.
Where to update the Token
In a service dedicated to Token management. This is the best practice.
More information
You said you had an Auth Guard. This is a good practice. but yes, you can redirect the user from your service. Why wouldn't you ? That's the usual way of asking an user to connect ! Use the router in your service, really, there's no issue with that.
From my point of view, and what you described, except for the routing in a guard, you're doing it pretty well. The only advice I would give you is to handle an expiration date on your token, if your application is high risk profiled (and you have to use the session storage).
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.
I know of two ways of storing and authenticating the user login info:
Storing the user id in a server side session and then when someone calls to the server check if they have a user session. (Using node client sessions)
When the user logins, store a authentication token in the user's table and store the token locally on the users client as well. Then when the user calls to the server they send the authentication token as a header and check if the token is in the user table.
While both of these ways are viable and applicable, I have problems/questions with both of them:
I've been told storing the info in session goes against the rest api idea of auto scalability. Is this true and is there a way around it?
When storing the authentication key, won't you only be able to store one key/instance per user. What would you do if you wanted to have the same account logged in on two computers or clients (I know I can just create an authentication table, but what if a client loses a token and the authentication token stays forever in the authentication table).
If there are better ways of doing this please bring it up, but I am very confused which direction to move towards. I am gravitating toward the second way, but I still like the first way.
Edit: I have narrowed it down to JWT and my second idea. I don't know which would be better with node.
How about JSON Web Tokens? They're a variant of the second method you mention and are a recognised industry standard, so you can easily find an implementation for your stack.
You can store the tokens in a key-value store like Redis instead of a relational database, which will be much faster. Redis also supports timing out a key after a while, so expired tokens will disappear automatically. You can also set it up so that each token is invalidated once used, and any request to the API returns a new token for use in the next request, allowing users to continually refresh their token.
Assuming you are using express, you can use express-session for managing your sessions.
Then, you need to add a suitable session store instead of the default MemoryStore, which is for debug use only, and will not scale to more than one process instance (for the reasons you mentioned in your question).
Fro example, if you are using a PostgreSQL database, you could consider using connect-pg-simple. This would store your sessions in your DB, so that your session management does not prevent you from scaling your node.js server. In addition, you can store multiple sessions per user, that will expire (and get automatically erased) based on the maxAge that you configure, thus solving the second problem you mentioned.
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.