__NEXT_REDUX_WRAPPER_HYDRATE__ cookie bug
zhangwei900808 opened this issue · 15 comments
User B login info must null but B got User A login info why???
store.js
export const initStore = configureStore({
reducer: combinedReducers,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().prepend(
nextReduxCookieMiddleware({
// 是否压缩
// compress: false,
subtrees: ["auth.accessToken", "auth.refreshToken", "auth.isLogin", "auth.me"],
})
).concat(logger)
})
authSlice.js
// 初始化数据
const internalInitialState = {
accessToken: null,
refreshToken: null,
me: null,
errorMsg: null,
isLogin: false,
isExpired: false
};
// reducer
export const authSlice = createSlice({
name: 'auth',
initialState: internalInitialState,
reducers: {
updateAuth(state, action) {
state.accessToken = action.payload.accessToken;
state.me = action.payload.me;
},
reset: () => internalInitialState,
setExpired(state, action) {
state.isExpired = action.payload;
},
getRefreshToken(state, action) {
return state.refreshToken;
},
setAuth(state, action) {
console.log('-----------setAuth-----------', action)
if (action.payload) {
state.accessToken = action.payload.accessToken;
state.refreshToken = action.payload.refreshToken;
state.isLogin = action.payload.isLogin;
state.isExpired = action.payload.isExpired;
}
}
},
extraReducers: {
// 水合,拿到服务器端的reducer注入到客户端的reducer,达到数据统一的目的
[HYDRATE]: (state, action) => {
console.log('-------------------------------------------------------')
console.log('----------------------AUTH HYDRATE---------------------')
console.log('-------------------------------------------------------')
// console.log('HYDRATE', state, action.payload);
return {
...state,
...action.payload.auth,
};
},
@bjoluc I found the reason and recurrent
when I remove User B cookie(no anything) and refresh User A(user A had login ) chrome then refresh User B chrome is appear!!!
but When I don't remove User B cookie(has null cookie) and refresh User A(user A had login ) chrome then refresh User B chrome its worked!!!
So the User B cookie must have value in chrome ,else appear this bug how to resolve it ???
Hi @zhangwei900808,
I'm not sure if I fully get your issue. To me, it sounds like two browser instances on your machine share cookies. Anyway, any behavior across browser tabs is up to your browser or application and not next-redux-cookie-wrapper. I'm going to close this as unrelated. Anyway, best of success resolving it!
@bjoluc you dont understand
1、is not share cookie
2、is next-redux-cookie-wrapper bug
eg:
User A in Beijing and User B in Shanghai
when User A open website and login then next-redux-cookie-wrapper set cookie in chrome
when User B open website not login but he got User A cookie in him chrome
so Why appear it???
I tend to be very careful myself about calling out bugs in libraries without putting together a minimal reproducible example, and I'm afraid I can't help you without a self-contained repro repository. Get active and track down the cause of the problem, and when you know which component/library causes it, please come back here with a minimal repro repo and I'll be happy to investigate further. You may also take a look here.
redux-toolkit-cookie-wrapper-bug
@bjoluc You take a look
Thanks for the repro @zhangwei900808. Your problem is unrelated and took some time for me to spot: The behavior you are facing is due to a single shared store instance on the server due to a faulty initStore
definition. In your repro you write
export const initStore = configureStore({...});
export const store = wrapMakeStore(() => initStore);
export const wrapper = createWrapper(store, {...});
which should be something along these lines:
const makeStore = () => configureStore({...});
const wrappedMakeStore = wrapMakeStore(makeStore);
export const wrapper = createWrapper(wrappedMakeStore, {...});
or simply as in the demo:
const makeStore = wrapMakeStore(() => configureStore({...}));
export const wrapper = createWrapper(makeStore, {...});
Cheers!
@bjoluc It's Worked! I was so sorry for that and very THKS^_^!
but that a litter problem that how can I get dispatch in makeStore?
when I used below code is have a problem is not got refresh token ,tips me is null!
import axios from 'axios';
import createAuthRefreshInterceptor from "axios-auth-refresh";
import {refreshToken} from '@/store/slices/authSlice'
import {initStore} from '@/store'
const axiosInstance = axios.create({
baseURL: `${process.env.NEXT_PUBLIC_API_HOST}`,
withCredentials: false,
});
// refresh token when 401
createAuthRefreshInterceptor(axiosInstance, async failedRequest => {
const {dispatch} = initStore();
const res = await dispatch(refreshToken());
console.log('============createAuthRefreshInterceptor callback=======', res.payload)
if (res.payload && res.payload.accessToken)
failedRequest.response.config.headers.Authorization = 'Bearer ' + res.payload.accessToken;
return Promise.resolve();
});
export default axiosInstance;
export const refreshToken = createAsyncThunk('auth/refreshToken', async (params, thunkAPI) => {
try {
const {refreshToken} = thunkAPI.getState().auth;
if (refreshToken) {
console.log('==== refreshToken ====', refreshToken)
const response = await axios.post('/auth/oauth/token', qs.stringify({
grant_type: 'refresh_token',
refresh_token: refreshToken
}));
const resdata = response.data;
console.log('====refreshToken resdata ====', resdata)
if (resdata.access_token) {
// const refetch = await axios.get('/account/me', {
// headers: {Authorization: `Bearer ${resdata.access_token}`},
// });
// console.log('====refreshToken return1 ====', resdata)
return {
accessToken: resdata.access_token,
refreshToken: resdata.refresh_token,
isLogin: true,
isExpired: false,
// me: {
// name: refetch.data.name,
// avatar: refetch.data.avatar
// }
};
} else {
return thunkAPI.rejectWithValue({errorMsg: response.data.message});
}
} else {
return thunkAPI.rejectWithValue({errorMsg: "no refreshToken"});
}
} catch (error) {
return thunkAPI.rejectWithValue({errorMsg: error.message});
}
});
I created a mine middle and set axios 401 methods , Its Worked!
export const initStore = () => configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().prepend(
nextReduxCookieMiddleware({
// 是否压缩
// compress: false,
subtrees: ["auth.accessToken", "auth.refreshToken", "auth.isLogin", "auth.me"],
})
).concat((store) => (next) => (action) => {
// refresh token when 401
createAuthRefreshInterceptor(axiosInstance, async failedRequest => {
const res = await store.dispatch(refreshToken());
console.log('============createAuthRefreshInterceptor callback=======', res.payload)
if (res.payload && res.payload.accessToken)
failedRequest.response.config.headers.Authorization = 'Bearer ' + res.payload.accessToken;
return Promise.resolve();
});
//自定义中间件作用:如果上面的判断不返回则会报错,所以返回了一个空的自定义中间件
return next(action);
}).concat(process.env.NODE_ENV === `development` ? logger : (store) => (next) => (action) => {
//自定义中间件作用:如果上面的判断不返回则会报错,所以返回了一个空的自定义中间件
return next(action);
})
})