2

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.

1 Answer 1

3

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

Sign up to request clarification or add additional context in comments.

2 Comments

I will take a look at js-cookie. I'll get back to you in a minute :)
I believe it's Cookies.get and Cookies.set

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.