Reputation: 451
I am working on one project but I am wondering that if I am already using redux in our application then can we stop using httponly cookie to store token ?
This is my reducer and I am storing the token this way in my reducer. And I am also using redux-persist to persist the user whenever he reload the page.
So, it advisable to store the jwt token like this ?
import * as types from "./user.types";
const initialState = {
token: null,
user: {},
loading: false,
error: null,
};
const authReducer = (state = initialState, action) => {
switch (action.type) {
case types.LOGIN_START:
return {
...state,
loading: true,
};
case types.LOGIN_SUCCESS:
return {
...state,
loading: false,
token: action.payload.jwt,
user: action.payload.user,
};
case types.LOGIN_FAIL:
return {
...state,
loading: false,
error: action.payload,
};
default:
return state;
}
};
export default authReducer;
Upvotes: 2
Views: 10646
Reputation: 43
You should never store JWT tokens inside your localStorage since they are vulnerable to client side attacks like XSS or CSRF attacks.
Upvotes: 0
Reputation: 777
You can keep it in the store and you should also set a timeout for the token expiration that will logout the user once token expires.
I have added a package that let's you decode a token to retrieve exp
expiration time of the token and you can change it to work with redux-persist
import jwt_decode from "jwt-decode";
const token = localStorage.getItem('token')
const initialState = {
token: null,
user: {},
loading: false,
error: null,
};
if(token) {
try {
const jwt_decoded = jwt_decode(token)
const timeToExpire = jwt_decoded.exp - Date.now()
if(timeToExpire > 0) {
setTimeout(() => {
// dispatch action to logout
}, timeToExpire);
initialState.token = token;
}
} catch (error) {
console.log("error parsing token")
}
}
const authReducer = (state = initialState, action) => {
// your reducer code here
};
Note: There is actually no need to store it in the redux store, instead save to localStorage and where needed you can just read from storage and pass it.
Upvotes: 5
Reputation: 366
This way you have to send login request with every refresh as with every page reload redux store reload also.
Better you should save the token in local storage and pull in redux store as initial value so it automatically save with every reload.
In Store:
import { applyMiddleware, combineReducers, compose, createStore } from "redux";
const composeEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; //for redux extension
const initialState = {
token: {
token: localStorage.getItem("token")
? JSON.parse(localStorage.getItem("token"))
: null,
},
};
const store = createStore(
reducer,
initialState,
composeEnhancer(applyMiddleware(thunk))
);
Upvotes: 1