Redux Saga拦截API校验AccessToken及自定义中间件不触发问题
方案合理性说明
你描述的令牌校验流程用Redux中间件实现是合理的。Redux中间件的核心定位就是在action分发到reducer/业务逻辑层之前做统一拦截处理,你的需求里的统一拦截请求、令牌有效性校验、刷新令牌、重试原请求的逻辑,放在独立中间件里可以和业务逻辑完全解耦,避免每个业务请求重复写相同的校验逻辑。
现有代码的错误点
- 混淆了普通Redux中间件和Saga中间件的用法
你写的jwtSaga是符合Redux中间件规范的普通函数(结构为(store) => (next) => (action) => {}),并不是Saga生成器函数,不应该用createSagaMiddleware()来创建实例,也不需要调用.run()方法执行。你现在把普通中间件当成Saga中间件注册,自然无法触发执行。 - 中间件注册顺序错误
Redux中间件的执行顺序和applyMiddleware传入的顺序完全一致,你需要在请求到达业务Saga之前拦截action,就必须把JWT校验中间件放在sagaMiddleware前面,否则action会先被业务Saga处理,拦截逻辑完全失效。 - 注册逻辑混乱
你既在applyMiddleware的参数末尾单独传了JWTMiddleware,又注释了数组内的推入逻辑,代码逻辑不统一,进一步导致执行顺序不符合预期。
修正后的代码示例
store配置修改
import { createStore, applyMiddleware, compose } from 'redux'; import createSagaMiddleware from 'redux-saga'; import AppReducers from './reducers'; import rootSaga from './sagas'; // 直接导入你写的普通JWT中间件 import jwtMiddleware from './你的jwt中间件文件路径'; const sagaMiddleware = createSagaMiddleware(); // 按执行顺序排列中间件:JWT校验在前,业务Saga在后 const middleware = [jwtMiddleware, sagaMiddleware]; const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; const AppStore = createStore( AppReducers, composeEnhancers(applyMiddleware(...middleware)) ); // 只需要运行业务Saga即可,普通中间件不需要run sagaMiddleware.run(rootSaga); export default AppStore;
JWT中间件无需修改
你当前写的测试用JWT中间件逻辑本身是符合规范的,不需要调整,调整注册逻辑后即可正常打印日志。
后续实现提示
后续要实现令牌刷新、挂起重试原请求的逻辑时,需要在中间件内维护一个刷新令牌的状态锁,避免多个请求同时触发多次令牌刷新请求,刷新完成后再批量重试所有挂起的请求即可。
内容的提问来源于stack exchange,提问作者Alina
相关产品推荐
相关产品推荐

