Is it safe to use useCnntext+useReducer to store JWT? And also what's the difference if I use redux
it's not about safe, it's about practicability.
JWT will be flushed by context if u reload page.
so it's better to store in localStorage or sessionStorage.
for safety issue, it's fine if you JWT key not exposed on front side.
Related
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.
I have been trying to add some security to my react app. I am using a JWT token and have been storing it in the local storage. Storing it in the local storage was not very appealing for me and i decided to move the token into react context using the context API. However, after some research i learned that storing the JWT in local storage isn't that bad, and i would still need the token there in order to let the user continue after a refresh.
So, if i am going to be storing the token there anyway, is it worth it to have a context object storing the user as well?
It seems to me that just doing localStorage.get("token") is all i need.
is it worth it?
Both context and localStorage are using the global state, having the same token stored in both places is an anti-pattern.
What I would suggest instead is storing the User information in the context, and the token in the local storage.
Do not store the jwt token in local storage since is vulnerable to XSS attack. So it is better using context API.
If a user logs in with user and password, he gets an new api key,
so react can access the Rest Api with his user account. How do you save this api key? And what happend if the user clicks 'refresh page'?
Of course I can initalize the Rest App every time with
<script>
window.REP_LOG_API_KEY = '19e8317a38b24af82da056f6ed36e831ea6b8f9bfcad996aaa56ec773f9f2e1d';
</script>
<script src="build/reactapp.js"></script>
but dont look very secure (but I like the idea of changing this key
every page request, if you have no single page application and react
is only used here and there).
To store the Api Key in a cookie would be also possible (secure but not
httponly, normally I only use safe cookies). Is this the only way?
I'm still not quite sure how to use react with a rest api
with individual api keys. Thany you.
The API key you are talking about is probably cookies/authentication token. If it is cookies, you need to enable httpOnly to prevent attacks. For authentication token, the most common way to store is in localStorage or sessionStorage. However, it is insecure, even with HTTPS and short expiry dates (and you do HAVE to use them). Putting it in Redux store is the same as putting it in a global js object where everyone can see.
What will protect your app is to check standard headers to verify the request is same origin (source and target origins check) and CSRF token. Also a common pattern is to verify the token signature before storing and using it. You can check out Auth0 blog on where to store it here: https://auth0.com/docs/security/store-tokens
There are several ways to do this. If you are using a state management library like Redux, MobX, Flux etc, then you can put it there.
Another place to store them is in the browser local storage. This will keep the token saved even if the user refreshes the page or open a new tab etc. Yet I am not 100% sure whether it's a safe thing to do.
Or you can attach it to the Rest Client itself. IMO, this is the best way to do it. I will summarize the steps to do that in brief.
Create a Rest Client by wrapping a solution like fetch-api or axios.
Add a module state, where you can store any data
Whenever making a call, check if there is a token, if a token is not there in the state, then authenticate first.
If the token is there, use it to make the api call. If the request fails with a 403(or may be 401. It depends) error, that means the token has possibly expired. So authenticate again and update the token.
Something like this,
class ApiClient {
constructor() {
this.token = null;
}
login(username, password) {
// make the call to login
// set this.token with the response
}
request() {
// Make the API call using the token
}
}
What will happen with a refresh? Then since the token is not there, the authentication will need to happen again. This will not be a problem if you use cookies to manage sessions.
You can put it in Redux store. I think it is the best implementation.
I'm developing an ReactJS app calling api from my server. After logging in, server returns an authentic-token and I need to store it in cookies (the key is token and value is the authentic-token from server. Now I'm using universal-cookie). But when I assign document.cookie to another value like token=xxx in browser's console, the token in cookies will be modified. Is there any ways to prevent user from modifying the cookie via document.cookie ?
Thank you !
To answer your question, the answer is No. You should never have to trust data from the browser as there are a myriad ways of manipulating it.
Instead you should make sure your backend server validates the cookie.
You cannot prevent a user from modifying the token in the cookies. universal-cookie stores data in a particular way and it shouldn't be altered using document.cookie. Also, you should always validate the data in the cookie with the data in your backend as the user can manipulate the data in any way.
It would be better to use universal-cookie itself to do all the tasks related to cookies you want to do, as you can do almost everything with it. And you can also try out some other packages such as react-cookies
I've read many debates for storing JWTs in localStorage, sessionStorage or HTTP Only cookies. It seems HTTP Only Cookies are the preferred storage mechanism due to XSS susceptibility in localStorage & sessionStorage.
When using Redux, why not just keep the JWT in state? (Besides the downside of having to re-log the user on every refresh). I'm sure this is obvious.
Yes, it is because of the downside of having to re-log the user on every refresh.
I believe that's quite a significant reason for a good and consistent user experience.