bjoluc / next-redux-cookie-wrapper

Sync a subset of your Redux state with cookies in Next.js :cookie: :sparkles:
MIT License
114 stars 4 forks source link

middleware sometime can't get subtrees #37

Closed zhangwei900808 closed 1 year ago

zhangwei900808 commented 2 years ago

store.js

import {axiosMiddleware} from './axiosMiddleware'

export const initStore = () => configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) => getDefaultMiddleware().prepend(
    nextReduxCookieMiddleware({
      // compress: true,
      subtrees: ["auth.accessToken", "auth.refreshToken", "auth.isLogin", "auth.me"],
    })
  ).concat(axiosMiddleware)
})

axiosMiddleware.js

export const axiosMiddleware = (store) => (next) => (action) => {
  createAuthRefreshInterceptor(axiosInstance, async failedRequest => {
    console.log('failedRequest=', store.getState().auth)
    const res = await store.dispatch(refreshToken());
    if (res.payload && res.payload.accessToken){
      const bearer = `Bearer ${res.payload.accessToken}`
      axiosInstance.defaults.headers.Authorization = bearer
      failedRequest.response.config.headers.Authorization = bearer
      return Promise.resolve();
    }else{
      return Promise.reject()
    }
  });
  return next(action);
}

look at console.log('failedRequest=', store.getState().auth) sometime I can get the auth state ,but sometime I cant get it why???

zhangwei900808 commented 2 years ago

refreshToken method have a problem

Not setting "auth.accessToken" cookie. Response has finished.
You should set cookie before res.send()
Not setting "auth.refreshToken" cookie. Response has finished.
You should set cookie before res.send()

authSlice.js

// 使用refresh token 获取 access token
export const refreshToken = createAsyncThunk('auth/refreshToken', async (params, thunkAPI) => {
  try {
    const {refreshToken} = thunkAPI.getState().auth;
    if (refreshToken) {
      console.log('==== refreshToken ====', refreshToken)
      delete axios.defaults.headers.Authorization;
      const response = await axios.post('/account/info/refreshToken', {
        refreshToken
      });

      const resdata = response.data;
      if (resdata.status === 0 && resdata.data.access_token) {
        return {
          accessToken: resdata.data.access_token,
          refreshToken: resdata.data.refresh_token,
          isLogin: true,
          isExpired: false
        };
      } else {
        return thunkAPI.rejectWithValue({errorMsg: "获取access token失败"});
      }
    } else {
      return thunkAPI.rejectWithValue({errorMsg: "no refreshToken"});
    }
  } catch (error) {
    return thunkAPI.rejectWithValue({errorMsg: error.message});
  }
});

[refreshToken.fulfilled]: (state, action) => {
  if (action.payload) {
    state.accessToken = action.payload.accessToken;
    state.refreshToken = action.payload.refreshToken;
    state.isLogin = action.payload.isLogin;
    state.isExpired = action.payload.isExpired;
  }
},
[refreshToken.rejected]: (state, action) => {
  state.accessToken = null;
  state.refreshToken = null;
  state.me = null;
  state.isLogin = false;
  state.isExpired = true;
},
bjoluc commented 2 years ago

Hi @zhangwei900808,

would you mind providing a repro?

bjoluc commented 1 year ago

Closing this as stale