1
1
1programmer2019-03-23 19:39:00
React
1programmer, 2019-03-23 19:39:00

Where can I write a token during authorization and receive data?

Hi all.
There is an api with authorization, when I request I get 2 refresh and token tokens.
At the same moment after authorization, I have to get information about the user, that is, send another request, fetchUser, passing the token in the headers via axios and transfer to a new page. The token is stored in cookies.


USER_REQUEST
USER_REQUEST_SUCCESS
USER_REQUEST_FAILURE

Let's say action.type
Question 1.
How should I set the header on subsequent visits to the site (when the token is in cookies)? When creating a store, take it directly Cookie.get('token') ?
Question 2.
At the first login, I get the user, but if I go to /main, for example, the store is empty and there is no user, because it only processes the request when the button on the login form is pressed, how can I get the user then?
I decided to add the IS_AUTH type and wrote it in configureStore.js, that is, every time I visit the site, it looks to see if there is a token in the cookie, if there is ok, if not, then the login page. But again, if I use this, the types that I wrote above do not work out for me and it turns out that I just go in, the token is in the cookies, but the store is empty and there is no information about the user
For authorization I use JWT
action/auth.js
import * as t from '../constants/actionTypes'
import axios from 'axios'
import { API_URL } from '../constants/default';
import Cookies from 'js-cookie'

export const saveToken = (login, password) => {
    return async dispatch => {
        dispatch({
            type: t.USER_REQUEST
        })

        try {
            let params = {
                login: login,
                password: password
            }
            const { data } = await axios.post(`${API_URL}/api/login`, params)


            if (data.hasOwnProperty('access_token')) {
                let refresh_expires_in = 1000 * 60 * 60 * 24 * 365 // 1 year
                Cookies.set('token', data.access_token, { expires: data.expires_in })
                Cookies.set('refresh_token', data.refresh_token, { expires: refresh_expires_in })
                dispatch({
                    type: t.USER_REQUEST_SUCCESS,
                    token: data.access_token,
                    refresh_token: data.refresh_token
                })
                fetchUser(data.access_token)
            }


        } catch (error) {

        }
    }
}

const fetchUser = async (token) => {
    axios.defaults.headers.common['Authorization'] = `Bearer ${token}`
    const { data } = await axios.get(`${API_URL}/api/user`)
    return console.log(data)

}

configureStore.js
import reducer from '../reducer'
import thunk from 'redux-thunk'
import logger from 'redux-logger'
import { createStore, applyMiddleware } from 'redux'
import Cookies from 'js-cookie'
import axios from 'axios'
import * as t from '../constants/actionTypes'


export const configureStore = () => {

    const store = createStore(reducer, applyMiddleware(thunk, logger))

    let token = Cookies.get('token')
    if (token != null) {
        axios.defaults.headers.common['Authorization'] = `Bearer ${token}`
        store.dispatch({
            type: t.IS_AUTH,
        })
    } else {
        Cookies.remove('token')
    }


    return store
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Anton Spirin, 2019-03-23
@1programmer

1. It makes no sense to do this when creating a store. Just confuse the code. It's worth doing it in an async action. When creating a store, is it appropriate to put an axios instance as an additional argument to redux-thunk, but only if you are using SSR.
2. Also in async action.
Create an init action and check for the presence of a token there, and load the data needed for initialization:

export function init() {
  return async (dispatch, getState) => {
    const token =  Cookies.get('token');

    if (token) {
      axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
      await dispatch(fetchUserData());
      // some other code
    } else {
      // else case code
    }
  };
}

Call init right after the store is created:
const store = configureStore();
store.dispatch.(init());

const Root = () => (
  <Provider store={store}>
    <Router>
      <App />
    </Router>
  </Provider>
);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question