ReactJS: How to implement react-cookie properly in an action?

11,892

I personally would rather using js-cookie to write/read cookies.

It has a very basic API:

Cookie.set('cookie_name', 'value') // will set "cookie_name" to "value"
Cookie.get('cookie_name') // will return "value"

Which means:

const login  = (email, pass, cookie) => {
    return (dispatch) => {
        dispatch({
            type: LOGIN
        })
        var url = api.logInApi
        axios.post(url, {
              email: email,
              password: pass
            })
            .then(res => {
                dispatch({
                    type: LOGIN_SUCCESS,
                    payload: res.data
                })
                cookies.set('token', res.data.token);
                dispatch(getUserData())
            })
            .catch(err => dispatch({
                type: LOGIN_FAILED,
                payload: err
            }))
    }
}

Passing to the login funuction js-cookie's Cookie in the 3rd argument.

Now, you can still use the same react-cookie package to read the cookie values (I believe there shouldn't be any conflicts). Or you can replace it with js-cookie. To do that, however, you will have to pass the Cookie object to props. I probably would do that using mapStateToProps if you're using Redux or just by simply passing it through JSX

Share:
11,892

Related videos on Youtube

eibersji
Author by

eibersji

Updated on June 04, 2022

Comments

  • eibersji
    eibersji almost 2 years

    I have read articles that saving the token in localstorage is dangerous to XSS attack. So I have decided to store my tokens in cookies. And I am using react-cookie. I saw the examples and I am trying to do it but my auth.js consists of const and is not a class, so I do not know how to use the withCookies() with it, this is my auth.js where I want to store the token to the cookies:

    import {
      LOGIN,
      LOGIN_SUCCESS,
      LOGIN_FAILED,
    
      GET_USER_DATA,
      GET_USER_DATA_SUCCESS,
      GET_USER_DATA_FAILED,
    
      LOGOUT,
      LOGOUT_SUCCESS,
      LOGOUT_FAILED,
    } from './types'
    
    import axios from 'axios'
    var api = require ('./../api.js');
    
    
    export const login = (email, pass) => {
        return (dispatch) => {
            dispatch({
                type: LOGIN
            })
            var url = api.logInApi
            axios.post(url, {
                  email: email,
                  password: pass
                })
                .then(res => {
                    dispatch({
                        type: LOGIN_SUCCESS,
                        payload: res.data
                    })
                    localStorage.setItem('token', res.data.token)
                    dispatch(getUserData())
                })
                .catch(err => dispatch({
                    type: LOGIN_FAILED,
                    payload: err
                }))
        }
    }
    
    
    
    export const getUserData = () => {
        return (dispatch) => {
            dispatch({
                type: GET_USER_DATA
            })
            var url = api.getUserDataApi
            axios.post(url, {}, {headers: {
                    "Authorization": `Bearer ${localStorage.getItem("token")}` 
                  }})
                .then(res => {
                    dispatch({
                        type: GET_USER_DATA_SUCCESS,
                        payload: res.data
                    })
                })
                .catch(err => dispatch({
                    type: GET_USER_DATA_FAILED,
                    payload: err
                }))
        }
    }
    
    
    export const logout = () => {
        return (dispatch) => {
            dispatch({
                type: LOGOUT
            })
            var url = api.logoutApi
            axios.post(url, {}, {headers: {
                    "Authorization": `Bearer ${localStorage.getItem("token")}` 
                  }})
                .then(res => {
                    window.location.replace("")
                    dispatch({
                        type: LOGOUT_SUCCESS,
                        payload: res.data
                    })
                })
                .catch(err => dispatch({
                    type: LOGOUT_FAILED,
                    payload: err
                }))
        }
    }
    

    Now, I tried doing this and of course it doesn't work:

    import {
      LOGIN,
      LOGIN_SUCCESS,
      LOGIN_FAILED,
    
      GET_USER_DATA,
      GET_USER_DATA_SUCCESS,
      GET_USER_DATA_FAILED,
    
      LOGOUT,
      LOGOUT_SUCCESS,
      LOGOUT_FAILED,
    } from './types'
    
    import axios from 'axios'
    import { withCookies, Cookies } from 'react-cookie'; <<added this
    var api = require ('./../api.js');
    
    const login  = (email, pass) => {
        return (dispatch) => {
            dispatch({
                type: LOGIN
            })
            const { cookies } = props; <<added this
            var url = api.logInApi
            axios.post(url, {
                  email: email,
                  password: pass
                })
                .then(res => {
                    dispatch({
                        type: LOGIN_SUCCESS,
                        payload: res.data
                    })
                    cookies.set('token', res.data.token, { path: '/' }); <<added this
                    dispatch(getUserData())
                })
                .catch(err => dispatch({
                    type: LOGIN_FAILED,
                    payload: err
                }))
        }
    }
    export default withCookies(login) <<added this(wrong)
    
    
    
    const getUserData = () => {
        return (dispatch) => {
            dispatch({
                type: GET_USER_DATA
            })
            const { cookies } = props; <<added this
            var token = cookies.get('token'); <<added this
            var url = api.getUserDataApi
            axios.post(url, {}, {headers: {
                    "Authorization": `Bearer ${token}` <<added this(this is where I wanna get the cookie)
                  }})
                .then(res => {
                    dispatch({
                        type: GET_USER_DATA_SUCCESS,
                        payload: res.data
                    })
                })
                .catch(err => dispatch({
                    type: GET_USER_DATA_FAILED,
                    payload: err
                }))
        }
    }
    export default withCookies(getUserData) <<added this(wrong)
    
    
    const logout = () => {
        return (dispatch) => {
            dispatch({
                type: LOGOUT
            })
            const { cookies } = props;
            var token = cookies.get('token');
            var url = api.logoutApi
            axios.post(url, {}, {headers: {
                "Authorization": `Bearer ${token}` <<added this
                  }})
                .then(res => {
                    window.location.replace("")
                    dispatch({
                        type: LOGOUT_SUCCESS,
                        payload: res.data
                    })
                })
                .catch(err => dispatch({
                    type: LOGOUT_FAILED,
                    payload: err
                }))
        }
    }
    export default withCookies(logout) <<added this(wrong)
    

    this one is wrong because there should only be one export default. But I don't know how to implement withCookies to const and there are also these ones that are included in the example and I don't know if I need them or where do I put them:

      static propTypes = {
        cookies: instanceOf(Cookies).isRequired
      };
    
      constructor(props) {
        super(props);
    
        const { cookies } = props;
        this.state = {
          name: cookies.get('name') || 'Ben'
        };
      }
    

    and also, another question is that, I can access my cookies anywhere in my project right? just like how localstorage is accessible to my project?

    I hope someone can help me and I am a newbie to this. I have never used cookies before so thank you for your consideration.

  • eibersji
    eibersji over 5 years
    I will take a look at js-cookie. I'll get back to you in a minute :)
  • haventchecked
    haventchecked over 2 years
    I believe it's Cookies.get and Cookies.set