reactjs – 在React Router上,如何保持登录状态甚至刷新页面?
我正在使用React和React Router与Redux建立网站。许多路线(页面)需要登录。如果用户未登录,我可以重定向到登录:
function requireAuth(nextState,replace) { let loggedIn = store.getState().AppReducer.UserReducer.loggedIn; if(!loggedIn) { replace({ pathname: '/login',state: { nextpathname: nextState.location.pathname } }); } } ReactDOM.render( <Provider store={store}> <Router history={history}> <Route path="/" component={App}> <IndexRoute component={Index} /> <Route path="login" component={Login} /> <Route path="register" component={Register} /> <Route path="dashboard" component={Graph} onEnter={requireAuth}> ... some other route requires logged in ... </Route> </Route> </Router> </Provider>,document.getElementById('entry') ); 如果用户没有登录,请查看代码,我使用onEnter挂钩重定向到’/ login’路由。用于检查用户登录的数据在商店中,并且在用户登录后将更新。 它工作得很好,但问题是当我刷新页面时,存储将被重置并且用户没有登录状态。 我知道这是因为Redux存储只是内存存储,所以refesh页面会丢失所有数据。 检查服务器会话每次刷新都可以工作,但这可能是太多的请求,所以这看起来不错。 将登录的状态数据保存到localStorage可能有效,但在这种情况下,我应该检查每个AJAX调用是否因为会话过期或不存在而拒绝该请求,这看起来也是个坏主意。 有没有办法更清楚地解决这个问题?我的网站将会使用很多人,所以我希望尽可能减少XHR呼叫。 任何建议将非常感谢。
另一种方法是使用每条路线所需的
JSON Web Tokens (JWT),以及
localStorage来检查JWT。
TL; DR >在前端,您有一个登录和注册路径,可以查询您的 设置它需要一点时间,但它会使您的应用程序“合理”安全。 要解决您的问题: 检查index.js文件中路由之前的本地存储,如下所示,如果需要,将状态更新为已验证状态。 该应用程序通过JWT保护API以保护安全性,这将解决您的刷新问题,并维护与服务器和数据的安全链接。 因此在路线中你会有这样的东西: index.js import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import { createStore,applyMiddleware,compose } from 'redux'; import { Router,Route,browserHistory,IndexRoute } from 'react-router'; import reduxThunk from 'redux-thunk'; import { AUTHENTICATE_THE_USER } from './actions/types'; import RequireAuth from './components/auth/require_auth'; import reducers from './reducers'; /* ...import necessary components */ const createStoreWithMiddleware = compose(applyMiddleware(reduxThunk))(createStore); const store = createStoreWithMiddleware(reducers); /* ... */ // Check for token and update application state if required const token = localStorage.getItem('token'); if (token) { store.dispatch({ type: AUTHENTICATE_THE_USER }); } /* ... */ ReactDOM.render( <Provider store={store}> <Router history={history}> <Route path="/" component={App}> <IndexRoute component={Index} /> <Route path="login" component={Login} /> <Route path="register" component={Register} /> <Route path="dashboard" component={RequireAuth{Graph}} /> <Route path="isauthenticated" component={RequireAuth(IsAuthenticated)} /> ... some other route requires logged in ... </Route> </Router> </Provider>,.getElementById('entry')); RequiredAuth是组合组件,而Graph和IsAuthenticated(可以是任意数量的适当命名的组件)需要state.authenticated为true。 组件,在这种情况下,如果state.authenticated为true,则呈现Graph和IsAuthenticated。否则默认返回根路由。 然后你可以像这样构建一个Composed Component,通过它来渲染所有的路径。在渲染之前,它将检查您持有的状态,无论用户是否经过身份验证(布尔值)。 require_auth.js import React,{ Component } from 'react'; import { connect } from 'react-redux'; export default function (ComposedComponent) { // If user not authenticated render out to root class Authentication extends Component { static contextTypes = { router: React.PropTypes.object }; componentWillMount() { if (!this.props.authenticated) { this.context.router.push('/'); } } componentWillUpdate(nextProps) { if (!nextProps.authenticated) { this.context.router.push('/'); } } render() { return <ComposedComponent {...this.props} />; } } function mapStateToProps(state) { return { authenticated: state.authenticated }; } return connect(mapStateToProps)(Authentication); } 在注册/注册方面,您可以创建一个存储JWT的动作,并通过动作创建者设置要通过身份验证的状态 – > redux商店。此示例makes use of axios运行异步HTTP请求响应周期。 export function signinUser({ email,password }) { // Note using the npm package 'redux-thunk' // giving direct access to the dispatch method return function (dispatch) { // Submit email and password to server axios.post(`${API_URL}/signin`,{ email,password }) .then(response => { // If request is good update state - user is authenticated dispatch({ type: AUTHENTICATE_THE_USER }); // - Save the JWT in localStorage localStorage.setItem('token',response.data.token); // - redirect to the route '/isauthenticated' browserHistory.push('/isauthenticated'); }) .catch(() => { // If request is bad show an error to the user dispatch(authenticationError('Incorrect email or password!')); }); }; } 你还需要设置你的商店(在这种情况下是Redux)和行动创建者。 “真正的”安全性来自后端。为此,您可以使用localStorage将JWT保留在前端,并将其在标头中传递给任何具有敏感/受保护信息的API调用。 在服务器API上为用户创建和解析JWT是另一个步骤。 I have found passport to be effective. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |