I am doing a Website 100% in ReactJS, It's a simple/medium complex, this has a Login, Profile and other sections more. After Users Log into the site the login callback returns some important values like: "Token, UserRole". Currently I'm storing these values in Web client using localStorage .
My doubt is the next: There is a better way to store this values? Because if any person changes the value from the Browser Console this could be a BIG ISSUE because they could change the role and then execute things that they never should do.
I thought to do it with Redux, but if the users Refresh the website then they lost the values, so I am not pretty sure to choose this.
What do you think guys?
TIA!
CodePudding user response:
The general rule is to never trust any data stored client-side, except for an authentication token or the equivalent. All changes that the user makes that involves the server should be verified on the server. So, rather than:
if any person changes the value from the Browser Console this could be a BIG ISSUE because they could change the role and then execute things that they never should do
Instead, the right thing to do would be, when the client wants to do something (such as edit their profile), have the client send their authentication token (or session ID) with the rest of the payload to your server. Have your server examine the token, check that the user associated with the token actually does have the required permissions for what they want to do, and only then continue to process the request.
Whether you also happen to store some information in Redux or elsewhere has no impact.
Storing login-related information client-side is relatively common and isn't inherently bad - just make sure to always verify it on the server when something that requires permissions is requested.
One approach some use is for the server to create an encrypted JWT that only the server can decode, which gets sent with requests.
CodePudding user response:
You can store data using redux and redux-persist and then encrypt the data with redux-persist-transform-encrypt.
CodePudding user response:
necessary packages
redux-persist-transform-encrypt
Under the src folder, create a folder named Store or whatever you like. Within your created folder (in my case, Store), create files Constant.js, Store.js, rootReducer.js, and a folder User. Create two files under the User folder: Reducer.js and Action.js.
A user email can be stored in a secure way in the following way:
Constant.js
export const CHANGE_USER_EMAIL = 'CHANGE_USER_EMAIL';
Action.js
import {CHANGE_USER_EMAIL} from '../Constant.js';
export const SET_USER_EMAIL=(Email)=>({
type:CHANGE_USER_EMAIL,
payload:Email
})
Reducer.js
import {CHANGE_USER_EMAIL} from '../Constant.js';
const INITIAL_STATE = {
EMAIL: undefined
}
const USER_EMAIL=(state = INITIAL_STATE , action:any)=>{
switch(action.type){
case CHANGE_USER_EMAIL:
return {EMAIL:action.payload}
default:
return state;
}
}
export default USER_EMAIL;
rootReducer.js
import { combineReducers } from 'redux';
import { persistReducer } from 'redux-persist';
// Depending on your needs, you can decide what kind of storage you need.
import storage from 'redux-persist/lib/storage';
import USER_EMAIL from './USER/Reducer.js';
import { encryptTransform } from 'redux-persist-transform-encrypt';
const rootReducer = combineReducers({ EMAIL:USER_EMAIL });
const persistConfig = {
key: 'root',
storage,
whitelist: ['EMAIL','NAME', 'SELLER', 'ADMIN'],
transforms: [
encryptTransform({
secretKey: 'Your secret key...',
one rror: function (error) {
// Handle the error.
},
})
],
};
export default persistReducer(persistConfig, rootReducer);
Store.js
import { createStore, applyMiddleware } from 'redux';
import { persistStore } from 'redux-persist';
import rootReducer from './rootReducer.js';
const middlewares = [];
export const store = createStore(rootReducer,applyMiddleware(...middlewares));
export const persistor = persistStore(store);
The only thing you have to do now is connect redux to the App ( main.js )
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router } from "react-router-dom";
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import { store, persistor } from './Store/Store.js';
import App from './App'
ReactDOM.render(
<Provider store={store}>
<Router >
<PersistGate persistor={persistor}>
<App/>
</PersistGate>
</Router>
</Provider>
,document.getElementById('root')
)
to add more elements ( name, number, etc ) with it create a folder like User and link it to rootReducer.js and using the mapdispatchtoprops and mapstatetoprops you can update and read the data.