@1programmer

Куда мне писать токен при авторизации и получать данные?

Привет всем.
Есть api с авторизацией, при запрос получаю 2 токена refresh и token.
В этот же момент после авторизации я должен получить информацию о пользователе, то есть отправить еще один запрос, fetchUser, передав в заголовках через axios токен и перевести на новую страницу. Токен хранится в куках.

USER_REQUEST
USER_REQUEST_SUCCESS
USER_REQUEST_FAILURE

Вот допустим action.type
Вопрос 1.
Как я при последующих заходах на сайт (когда токен в куках) должен выставлять заголовок ? При создании стора брать на пряму Cookie.get('token') ?
Вопрос 2.
При первом входе я получаю пользователя, но если я перехожу на /main допустим, стор пустой и пользователя нет, потому что отрабатывает запрос только при нажатии кнопки на форме входа, как мне тогда получать пользователя ?
Я решил добавить тип IS_AUTH и написал его в configureStore.js то есть при каждом заходе на сайт, он смотрит есть ли в куках токен, если есть ок, если нет то страница входа. Но опять же если я использую это у меня не отрабатывают типы которые писал выше и получается что я просто захожу, токен в куках, но стор пустой и нету инфы о пользователе
Для авторизации использую 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
}
  • Вопрос задан
  • 634 просмотра
Решения вопроса 1
rockon404
@rockon404 Куратор тега React
Frontend Developer
1. Бессмысленно это делать при создании store. Только запутаете код. Делать это стоит в async action. При создании store разве уместно положить инстанс axios дополнительным аргументом в redux-thunk, но только если используете SSR.
2. Так же в async action.

Создайте действие init и проверяйте там наличие токена, и загружайте нужные для инициализации данные:
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
    }
  };
}


Вызывайте init сразу после создания store:
const store = configureStore();
store.dispatch.(init());

const Root = () => (
  <Provider store={store}>
    <Router>
      <App />
    </Router>
  </Provider>
);
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы