Могу ли я проверить токен в редукторе, не нарушая принципы проектирования React? - PullRequest
0 голосов
/ 24 февраля 2020

Я пытаюсь выяснить структуру моей аутентификации по токену jwt с помощью response / redux. Теперь, как я его настроил, я использую промежуточное программное обеспечение, которое сохраняет токен в локальном хранилище, когда отправляется действие ATTEMPT_LOGIN_SUCCESS (Примечание: безопасность локального хранилища не имеет значения).

Для начального состояния, вошел ли пользователь в систему, я в настоящее время получаю токен из локального хранилища и проверяю его внутри моего редуктора входа в систему. Мой вопрос заключается в том, является ли это место, куда я действительно должен поместить это logi c.

промежуточное ПО jwt-handler для сохранения токена:

import {ATTEMPT_LOGIN_SUCCESS} from "./dataTypes/login"

const jwtHandler = store => next => action => {

    switch(action.type){
        case ATTEMPT_LOGIN_SUCCESS:
            const token = action.payload;

            localStorage.setItem("token", token);
    }

    return next(action);
}

export default jwtHandler;

Редуктор входа в систему (код в вопросе находится сверху вниз к исходному состоянию):

import {
    ATTEMPT_LOGIN_BEGIN, ATTEMPT_LOGIN_FAIL, ATTEMPT_LOGIN_SUCCESS
} from "../dataTypes/login";

import authenticateToken from "./authenticateToken";

const token = localStorage.getItem("token");
const isValid = authenticateToken(token); //Decodes and checks date to ensure valid

if(!isValid){
    localStorage.setItem("token", "");
}

const initialState = {
    loading:false,
    errorMessage: "",
    success:false,
    isLoggedIn: isValid
};

const loginReducer = (state = initialState, action) => {
    switch (action.type) {
        case ATTEMPT_LOGIN_BEGIN:
            return {
                ...state,
                loading:true,
                errorMessage:""
            };
        case ATTEMPT_LOGIN_SUCCESS:
            return {
                ...state,
                loading:false,
                success:true,
                token:action.payload
            };
        case ATTEMPT_LOGIN_FAIL:
            return {
                ...state,
                loading:false,
                errorMessage:action.payload
            };
        default:
            return state;
    }
};

export default loginReducer;

Я чувствую, что может быть лучшее место, чтобы поставить мой, зарегистрирован в логи c, но я еще не нашел хорошего ответа в Интернете.

Ответы [ 2 ]

1 голос
/ 25 февраля 2020

Я предпочитаю ваш шаблон промежуточного программного обеспечения, но немного более централизованный:

ПРИМЕЧАНИЕ : это самоуверенный и просто примерный набросок

// middleware.js
import {
    INIT_SESSION, ATTEMPT_LOGIN_BEGIN, ATTEMPT_LOGIN_FAIL, ATTEMPT_LOGIN_SUCCESS, LOGOUT
} from "../dataTypes/login";

import authenticateToken from "./authenticateToken";

const jwtHandler = store => next => action => {

    switch(action.type){
        // INIT_SESSION handled only here not in any reducer
        case INIT_SESSION:
            const token = localStorage.getItem("token");
            const isValid = authenticateToken(token);
            if(valid){
            store.dispatch({type:ATTEMPT_LOGIN_SUCCESS, payload: token});
            } else {
             localStorage.removeItem("token");
            }
            break;

        case ATTEMPT_LOGIN_SUCCESS:
            const newToken = action.payload;
            localStorage.setItem("token", newToken);
           break;
        case LOGOUT:
          localStorage.removeItem("token");
           break;
        default:

    }

    return next(action);
}

export default jwtHandler;


// index.js
    const store = createStore();
    store.dispatch({type: INIT_SESSION});

    ReactDOM.render(<Provider store={store}>//...


// reducer.js stays clean...
0 голосов
/ 24 февраля 2020

В вашем редукторе вы можете сделать

const INITIAL_STATE = {
    // ...data
    loading:false,
    token: localStorage.getItem("token"),
};

export default (state = INITIAL_STATE, action) => {
    switch (action.type) {
        case ATTEMPT_LOGIN_BEGIN:
            return {
                ...state,
                loading: true,
            };
        case ATTEMPT_LOGIN_SUCCESS:
            localStorage.setItem("token", action.payload.token);
            return {
                ...state,
                loading: false,
                token: action.payload.token,
            };
        case ATTEMPT_LOGIN_FAILURE:
            localStorage.removeItem("token");
            return {
                ...state,
                loading: false,
                token: null,
            };
     }
 }
...