我正在开发一个带有登录页面的应用程序和应用程序的其余页面(应该登录才能查看)。我正在使用 react-boilerplate. 从此example,我asyncInjectors.js将文件编辑为具有redirectToLogin和redirectToDashboard方法:
//asyncInjectors.js
export function redirectToLogin(store) {
return (nextState, replaceState) => {
const isAuthenticated = store.getState().get('app').get('isAuthenticated');
if (!isAuthenticated) {
replaceState({
pathname: '/login',
state: {
nextPathname: nextState.location.pathname,
},
});
}
};
}
export function redirectToDashboard(store) {
return (nextState, replaceState) => {
const isAuthenticated = store.getState().get('app').get('isAuthenticated');
if (isAuthenticated) {
replaceState('/');
}
}
}
然后我只是将 设置redirectToLogin为onEnter页面和redirectToDashboard登录页面。
它工作正常,但是当登录时刷新页面 ( F5) 时,登录页面会短暂呈现,然后呈现实际页面。登录页面只是调度一个authenticate动作componentWillMount,然后重定向componentDidUpdate:
//login.js
componentWillMount() {
this.props.dispatch(authenticate());
}
componentDidUpdate(prevProps, prevState) {
if (this.props.isAuthenticated) {
const nextPathname = prevProps.location.state ? prevProps.location.state.nextPathname : '/';
browserHistory.push(nextPathname);
}
}
页面的容器也有相同的componentWillMount代码。不知道是不是因为传奇,但这里是代码:
//sagas.js
export function* login({ user, password }) {
try {
const token = yield call(app.authenticate, {
strategy: 'local',
user,
password,
});
return token;
} catch (error) {
return onError(error);
}
}
// For page refresh after logging in
export function* authenticate() {
try {
const token = yield call(app.authenticate);
return token;
} catch (error) {
return onError(error);
}
}
export function* logout() {
try {
const response = yield call(app.logout);
return response;
} catch (error) {
return onError(error);
}
}
export function* loginFlow() {
while (true) {
const request = yield take(LOGIN_REQUEST);
const winner = yield race({
auth: call(login, request.data),
logout: take(LOGOUT_REQUEST),
});
if (winner.auth && winner.auth.accessToken) {
yield put(actions.setAuthState(true));
}
}
}
export function* logoutFlow() {
while (true) {
yield take(LOGOUT_REQUEST);
yield put(actions.setAuthState(false));
yield call(logout);
browserHistory.push('/login');
}
}
export function* authenticateFlow() {
while (true) {
yield take(AUTHENTICATE);
const response = yield call(authenticate);
if (response && response.accessToken) {
yield put(actions.setAuthState(true));
}
}
}
export default [
loginFlow,
logoutFlow,
authenticateFlow,
];
如何摆脱闪烁的登录页面?
编辑:当我尝试gouroujo的答案时,我无法注销。
//asyncInjectors.js
import jwtDecode from 'jwt-decode';
export function redirectToLogin(store) {
return (nextState, replaceState, callback) => {
const token = localStorage.token;
if (token) {
const jwt = jwtDecode(token);
if (jwt.exp <= (new Date().getTime() / 1000)) {
store.dispatch(actions.setAuthState(false));
replaceState({
pathname: '/login',
state: {
nextPathname: nextState.location.pathname,
},
});
}
}
store.dispatch(actions.setAuthState(true));
callback();
};
}
当我点击刷新时,login page不显示,但现在我无法注销。