I'm building an AngularJS application that interacts with an API that uses authentication tokens to authenticate users. Everything seems to be working fine, but I'm struggling with a way to properly persist the authentication token between requests.
At the moment, when a user logs in with correct credentials an authToken is returned, and I'm setting that on $rootScope.authToken. I'm also sending that auth token for future requests, but if I do a hard reload reload the webpage with F5 $rootScope gets cleared and I have to authenticate again.
I'm aware I can store the authToken in a cookie, but would that be the most secure way? Am I better off using local storage to store the token? If local storage is used, would that not get cleared when the user restarts their browser? I'd ideally like the login to persist for a few days.
Firstly, I'm not sure what the format of your authToken is but localStorage should not be used for any sensitive data. Using localStorage works great (and survives browser restarts) as long as your authToken is relatively tamper-proof either through some form of encryption or nonce.
Essentially, you should be careful that since the value is "visible" to all client-side users it should be assumed to be possible to modify or increment.
Have you thought about revocation of login sessions? For example, if you want to log out all active sessions of your application, how would you do it? Since the authToken is stored client-side, you may need to add a timestamp (or some other unique value) to it that can be checked server-side.
Related
I have React signIn form and sessions mechanism implemented in NodeJs. In React I have protected routes only for authenticated users.
How should I check if user is authenticated. I have two ideas:
If user sign in for the fisrt time I can save this information in LocalStorage and then evrytime just check localStorage.
Send request to NodeJS server every time to check if user is authenticated.
Do you have any other ideas? Which solution should I pick?
I tried both options and second one is more UI unfriendly becasue I have to run loading state evrytime I am waiting for auth response. On the other hand, first option has also disadvantege, because I am based on token in LocalStorage which can be malicious.
Every time a request is made to an endpoint that requires authentication, the request should contain proof that they are who they claim to be.
The classic way to do this is by storing some sort of "Session ID" in a cookie or localStorage (client side), that you send along with every request.
Using a "Token" (e.g: JWT) instead of a "Session ID" is another popular way to handle authentication.
Check out this article for more information about both: https://dzone.com/articles/cookies-vs-tokens-the-definitive-guide
To return to your question, I'm not sure what you're worried about in regards to a "malicious Token in localStorage" (Or do you mean localStorage can be malicious?). But for a secure application you have to either:
Store something client-side
Require your user to provide credentials (username + password) for every request
I have an endpoint for authenticating the user, which takes the user's username and password. The request returns a token which the app should then use for all subsequent requests, so I store it in the Redux store.
The tokens have a limited lifetime, so the app has to get a new token every so often. Because of this, I want to store the username and password using the device's secure chain storage (I'm using React Native), not on the Redux store, since doing so make it easy to extract the credentials from the app memory.
But since RTK Query by default caches requests based on the args passed to it, the user credentials will be cached in the Redux store.
So my question is two-fold:
Is what I'm saying even sensible? Does the logic for how I want this to work makes sense?
If yes, then how do I go about disabling the cache for one specific endpoint for RTK Query?
The point of RTK Query is to put things into a Redux store. That is the core mechanism for everything.
You can do all the requests without it, but if you do a request with it, it will be cached, at least for a while.
That generally would not be much of a concern since a Redux store is just a variable like const foo = "somethingSecret" though.
That said, you should probably not store username and password, but a "refresh token" that you get from your server.
And usually, you should not store that yourself, but your fetch implementation should do that for you - in the form of a cookie.
This also works in React Native.
Your server just sets the cookie for both the token and the refresh token as a httpOnly cookie and you cannot even access them from JavaScript. In JS, you just say credential: "include" and all your requests to that same domain will contain those tokens.
Manually handling those tokens if you can avoid it is always bad security practice.
Maybe it's a silly question but I'm a bit confused about this.
I want to check whether a user is logged in or not but I don't want to use localStorage to save my JWT token. I know that I can easily save it in localStorage and check from there but for my application, I'm sending the JWT token through an HTTP-only cookie from the backend and from the frontend with every request I'm sending this.
So I'm confused if it is in an HTTP-only cookie I can't retrieve this through my script then how can I check the logged-in status except for local storage.
After googling sometimes I got one answer is using the redux-persist library to persist the application state but still under the hood it's doing the same job creating a copy of my state and saving it in local again which I don't want.
Anything else I can do about it or I have to use local storage ( maybe instead of saving the token I can save the user id or some other key: value pair)
In my React project, I have implemented authentication using Firebase authentication. Upon signing in successfully, the user details get stored in a 'user' object in the localStorage, and remain stored until the user specifically logs out. It is the presence of this 'user' object which is used to check whether the person is authenticated or not, and then subsequently open protected routes.
However, this method leads to a problem that one might copy the user details from the localStorage, and then set them manually using the console. This would lead to that user being signed in without authentication using their password.
So what is the correct and secure method to implement persistence of authentication in React
Like user object, any sensitive information should NOT be stored in localStorage, and the better option is to use HTTP only cookie.
This post answers your question and why you should use HTTP only cookie over localStorage:
https://stackoverflow.com/a/37396572/15881471
When used with the HttpOnly cookie flag, cookies are not accessible through JavaScript and are immune to XSS. You can also set the Secure cookie flag to guarantee the cookie is only sent over HTTPS
QUICK BACKGROUND:
I'm writing a Mongo/Express/Angular/Node SPA and using passport I have setup OAuth log in options to handle the user authentication / authorization.
With passport I am successfully maintaining session on the server, so all my XHR requests (that need it) are checking for a logged in user.
On log in the server puts the basic user session info into a cookie for the client to find on the authorization callback, I then am using angular-cookies' $CookieStore to access that cookie on the client save it to the rootscope and clear the cookie.
PROBLEM:
This is working perfectly except for any event where the user refreshes the browser, which causes my rootscope session to obviously get wiped.
So I was considering storing session information in the browser local storage (using store.js) then even on the initial load I could check for the session existing in the browser local storage and bypass the OAuth login if there was already a session.
Is it bad practice or is there some logistical/security problems with storing user session information in the browser local storage?
This app doesn't have any senstive data, sign up is free and logging in is really only there so I can track users and store data created in the application for each user. And the user session would never have a password (I only allow OAuth login no local option).
Instead of the localStorage, look at sessionStorage object: http://www.w3schools.com/html/html5_webstorage.asp
It works exactly like localStorage, but the whole sessionStorage object will be deleted when the browser window is closed - but will survive any page refreshes. It is an ideal place for storing session ids and alike.
But be warned that the sessionStorage is isolated within a browser tab - that means if your user choses to open a link in a new tab, the sessionStorage for that will be initialized empty.