我想在用户需要时“保持用户登录”。这样,用户不必在每次访问该网站时都登录。
这是我的做法。 1.当用户单击“保持登录状态”按钮时,redux存储中的“ keepLoggedIn”状态设置为“ true”,该存储使用“ redux-persist”存储在本地存储中。 2.在App.js中,使用window.onunload()检测到窗口/选项卡关闭,如果'keepLoggedIn'状态为'false',则清除localStorage,这将注销用户。
问题 window.onunload()还会检测窗口刷新和重新加载。从而使用户无法登录。
一些想法
有些人建议添加keydown条件以检测刷新。但是当他单击浏览器上的“刷新页面”按钮时,这并没有涵盖。
使用window.onload(这意味着使HTTPS请求每个刷新和重新加载页面)再次登录用户来检查JWT令牌将是多余的。
使用window.onunload可能不是正确的方法。有没有正确,更好的工作流程?
const App = ({ messageShow, isOnModal, keepLoggedIn, children }) => {
// keep me logged in when window/tab closed
window.onbeforeunload = () => {
window.onunload = () => {
if (!keepLoggedIn) clearLocalStorage();
};
return undefined;
};
return (
<div id="app absolute">
<NavContainer />
...
{children}
</div>
);
};
export default connect(
mapPropsToState,
null,
)(App);
----------------------------------版本------------ --------------------
import { applyMiddleware, createStore } from 'redux';
import thunkMiddleware from 'redux-thunk';
import { createLogger } from 'redux-logger';
import { composeWithDevTools } from 'redux-devtools-extension';
import { routerMiddleware, connectRouter } from 'connected-react-router';
import createBrowserHistory from 'history/createBrowserHistory';
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import storageSession from 'redux-persist/lib/storage/session';
import rootReducer from './src/reducers';
export const history = createBrowserHistory();
const middlewares = [
routerMiddleware(history),
thunkMiddleware,
createLogger({
predicate: () => process.env.NODE_ENV === 'development',
collapsed: true,
}),
];
const enhancers = [applyMiddleware(...middlewares)];
const persistConfig = {
key: 'root',
storage,
};
const persistedReducer = persistReducer(
persistConfig,
rootReducer(history),
);
export default function configureStore(preloadedState) {
const store = createStore(
persistedReducer,
preloadedState,
composeWithDevTools(...enhancers),
);
const persistor = persistStore(store);
return { store, persistor };
}
为了有条件地使用sessionStorage,我需要找到一种在存储配置中获取redux状态的方法。 “ get.store()”不起作用,因为需要在存储之前配置持久性。
const persistConfig = {
key: 'root',
keepLoggedIn ? storage : sessionStorage,
};
答案 0 :(得分:0)
对于可能与我有相同问题的人。 我通过使用@@ bb31建议的sessionStorage来“不要让我保持登录状态”,使用localStorage来“让我保持登录状态”来解决该问题。
这是我的工作方式。
在“保持登录状态”复选框单击时,在redux存储中将“ keepLoggedIn”状态(布尔值)更改为true。
如果“不要让我保持登录状态”,则在单击登录提交按钮时将'keepLoggedIn'状态保存在sessionStorage中。
const saveUserToken = (token, keepLoggedIn) => {
localStorage.setItem('token', token);
return !keepLoggedIn ?
sessionStorage.setItem('keepLoggedIn',keepLoggedIn): null;
};
这是当用户'keepLoggedIn'为false时检测浏览器刷新的方法。 创建一个HOC 并将其添加到路由中,以便在呈现要保护的任何网页之前呈现此HOC。 检查用户是否重新打开浏览器,如果是,请重置身份验证状态并清除localStorage以便注销用户。 否则,只需返回一个组件即可呈现页面。
如果sessionStorage为空,则重新打开浏览器,也不刷新浏览器。
我还检查'isLoggedIn'状态(在用户登录时设置为true)是否为false,以确保在用户登录时不注销用户。
class LoginAuth extends React.Component {
componentWillMount() {
const {
keepLoggedIn,
isLoggedIn,
userLogout,
history,
} = this.props;
if (
(!keepLoggedIn && !sessionStorage.getItem('keepLoggedIn')) ||
!isLoggedIn
) {
userLogout();
clearStorage();
return history.push('/login');
}
}
render() {
return <Component {...this.props} />;
}
}
const routes = props => (
<div>
<App history={props.history} />
<Switch>
<Route exact path="/" component={Home} />
<LoggedOutRoute path="/login" component={Login} />
<LoggedOutRoute path="/auth/forgot" component={Forgot} />
<Route path="/reset" component={Reset} />
<Route
exact
path="/user/account/me"
component={RouteGuards(UserAccount)}
/>
<Route component={NoMatch} />
</Switch>
</div>
);