2017-09-13 26 views
3

私はreactjs/reduxアプリケーションで作業していて、APIとして動作するJava Spring Bootコードベースを使用しています。Reactjs、Redux - redux-persist

私はログインシステムを用意していますが、私はページを更新すると認証状態が失われることに気づいています。

私はredux-persistを追加しましたが、ログインした状態を隠してから再開するようなことはありませんか?

redux-persistの大部分は、router.js ---ここでストア/プロバイダがアプリケーションに設定されている場所です。

ユーザーがログインしたときの状態と保存方法がわかりません - ログイン用のフォームが公開されていますが、this.props.authDataの状態を確認することができますpersistor.rehydrate()を呼び出すのが理想的でしょう - しかし、私はpersistorやそのページの店にアクセスできません。

//router.js

import React, { Component } from 'react' 
import { BrowserRouter as Router, Route, Redirect, Switch } from 'react-router-dom' 
import createBrowserHistory from 'history/createBrowserHistory' 
import { Provider } from 'react-redux' 
import { createStore, applyMiddleware } from 'redux' 
import thunk from 'redux-thunk'; 
import {persistStore, autoRehydrate} from 'redux-persist' 

import rootReducer from './reducers/rootReducer' 

// components 
import Login from './components/Login/Login' 
import ForgotPassword from './components/ForgotPassword/ForgotPassword' 
import RegisterUser from './components/RegisterUser/RegisterUser' 

import Home from './components/Home/Home' 
import Actions from './components/Actions/Actions' 
import AddSDQ from './components/Actions/AddSDQ' 

import PastSDQ from './components/PastSDQ/PastSDQ' 
import Account from './components/Account/Account' 

import Logout from './components/Logout/Logout' 

import About from './components/About/About' 
import Terms from './components/Terms/Terms' 
import Privacy from './components/Privacy/Privacy' 

import Error from './components/Error/Error' 

import Header from './components/Header/Header' 
import Footer from './components/Footer/Footer' 

const history = createBrowserHistory() 

// add `autoRehydrate` as an enhancer to your store (note: `autoRehydrate` is not a middleware) 
const store = createStore(
    rootReducer, 
    applyMiddleware(thunk), 
    autoRehydrate() 
); 

const persistor = persistStore(store, {},() => { 
    console.log('restored'); 
}) 

// we can pass the lang files as props to the routes 
// we should have a nested route inside service here to show the other services page 

class Routes extends Component { 

    constructor (props) { 
    super(props) 

    /* 
    this.state = { 
     rehydrated: false 
    }*/ 
    //console.log("router level", this.props) 
    //console.log("state-->", this.state) 
    } 

    componentWillMount(){ 
    // begin periodically persisting the store 
    /* 
    persistStore(store, {},() => { 
     this.setState({ rehydrated: true }) 
     console.log("rehydrated", store); 
    })*/ 
    } 

    render() { 

    console.log("this props", this); 

    // when the user has logged in - navigate them to the home page 
    if(this.props.authData){ 
     //this.props.authData.isLogged 
     //return <Redirect to='/home'/>; 
     console.log("user logged!!!!!!!!!!!"); 
     //persistor.rehydrate()//calls reducer to rehydrate store 
    } 


    const loggedIn = true;//this.state.isLoggedIn; 
    console.log("rendered store", store); 

    return (
     <Provider store={store}> 
     <Router history={history}> 
      <div className='off-canvas-wrap' data-offcanvas> 
      <div className='inner-wrap'> 
       <Header transparent /> 
       <Switch> 
       <Route path='/home' component={Home} /> 
       <Route path='/past-sdq' component={PastSDQ} /> 
       <Route path='/actions' component={Actions} /> 
       <Route path='/add-sdq' component={AddSDQ} /> 

       <Route path='/account' component={Account} /> 

       <Route path='/about' component={About} /> 
       <Route path='/terms' component={Terms} /> 
       <Route path='/privacy' component={Privacy} /> 

       <Route path='/login' component={Login} /> 
       <Route path='/logout' component={Logout} /> 
       <Route path='/forgot-password' component={ForgotPassword} /> 
       <Route path='/register-user' component={RegisterUser} /> 

       {/*<Route path='/api/:serviceRequest' />*/} 

       <Route exact path="/" render={() => (loggedIn ? (<Home/>) : (<Redirect to="/login"/>))} /> 

       <Route component={Error} /> 
       </Switch> 
       <Footer transparent /> 
      </div> 
      </div> 
     </Router> 
     </Provider> 
    ) 
    } 
} 

export default Routes 

//rootReducer.js

import { combineReducers } from 'redux' 
import { reducer as formReducer } from 'redux-form' 

import { authReducer } from './authReducer' 
import { regReducer } from './regReducer' 
import { forgotReducer } from './forgotReducer' 
import { homeReducer } from './homeReducer' 
import { editProfileReducer } from './editProfileReducer' 
import { initProfileReducer } from './initProfileReducer' 
import { editFollowUpReducer } from './editFollowUpReducer' 
import { initFollowUpReducer } from './initFollowUpReducer' 
import { addSDQReducer } from './addSDQReducer' 
import { pastSDQReducer } from './pastSDQReducer' 

import { rehydrateReducer } from './rehydrateReducer' 


const rootReducer = combineReducers({ 
    form: formReducer, 
    auth: authReducer, 
    reg: regReducer, 
    forgot: forgotReducer, 
    home: homeReducer, 
    editProfile: editProfileReducer, 
    initProfile: initProfileReducer, 
    editFollowUp: editFollowUpReducer, 
    initFollowUp: initFollowUpReducer, 
    addSDQ: addSDQReducer, 
    pastSDQ: pastSDQReducer, 
    rehydrate: rehydrateReducer 
}) 

export default rootReducer 

//rehydrateReducer.js

import {REHYDRATE} from 'redux-persist/constants' 

export function rehydrateReducer (state = {}, action) { 
    //console.log('reducer REHYDRATE act', action) 
    switch (action.type) { 
    case REHYDRATE: 
     return {...state, data: action.payload}; 
    default: 
     return {...state} 
    } 
} 

//login.js

import React, { Component } from 'react' 
import { withRouter, Redirect } from 'react-router-dom'; 
//import { withRouter, Redirect } from 'react-router-dom'; 
import { connect } from 'react-redux'; 
import { bindActionCreators } from 'redux'; 
import { fetchAuthentication } from '../../actions/authAction'; 

import {persistStore} from 'redux-persist' 

import { Row, Col } from 'antd'; 

// components 
import LoginSyncValidationForm from './LoginSyncValidationForm' 

import '../../forms.scss'; 


// this is a class because it needs state 
class Login extends Component { 

    constructor(props, context) { 
    super(props, context); 
    this.submit = this.submit.bind(this); 
    } 

    /* 
    static propTypes = { 
    isDark: React.PropTypes.bool 
    } 
    static defaultProps = { 
    isDark: false 
    } 
    */ 

    componentDidMount() { 
    //document.body.classList.toggle('darkClass', this.props.isDark) 
    } 
    componentWillReceiveProps(nextProps) { 
    //document.body.classList.toggle('darkClass', nextProps.isDark) 
    } 

    componentWillMount() { 
    document.body.classList.add('screenbackground'); 
    } 

    componentWillUnmount() { 
    document.body.classList.remove('screenbackground'); 
    } 

    submit(data) { 
    this.props.fetchAuthentication(data); 
    } 

    render() { 

    var errorPlaceholder = ""; 

    //console.log("authss-->", this.props.authData); 
    if(this.props.authData.data){ 

     //console.log("status--<", this.props.authData.data.data.status); 
     //if error from server side show the message 
     if(this.props.authData.data.data.status !== "success"){ 
     errorPlaceholder = this.props.authData.data.data.msg; 
     } 
    } 


    // when the user has logged in - navigate them to the home page 
    if(this.props.authData.isLogged){ 
     //return <Redirect to='/home'/>; 

     //persistor.rehydrate()//calls reducer to rehydrate store 
    } 

    return (
     <div className="Page form-components light"> 
     <h2>Login</h2> 
     <Row> 
      <Col xs={24} sm={24} md={10}> 
      <p>Welcome to the SLAM SDQ tracker. Because you are accessing sensitive info, you need to verify your identity using our secure login system. This will not only protect your data, but will provide a platform where you can be in control of your progress. Your unique identification number has been sent to you by e-mail. Use it to login. If you have not created an account yet or have forgotten your password, please use the links below to complete the desired action.</p> 
      </Col> 
      <Col xs={24} sm={24} md={24}> 
      <Row> 
       <Col xs={24} sm={24} md={6}> 
       <LoginSyncValidationForm onSubmit={this.submit} /> 
       </Col> 
      </Row> 
      </Col> 
      {errorPlaceholder.length > 0 && 
      <Col xs={24} sm={24} md={24}> 
       {errorPlaceholder} 
      </Col> 
      } 
     </Row> 
     <div className="shell" /> 
     <div className="screen-background login"/> 
     </div> 
    ) 
    } 

} 

function mapStateToProps(state) { 
    return { 
    authData: state.auth 
    }; 
} 

function mapDispatchToProps(dispatch) { 
return bindActionCreators({ fetchAuthentication }, dispatch); 
} 

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Login)) 

アップデート1:14/09/2017

これは私のauthAction.jsが

//authAction.js

import axios from 'axios'; 

    export const FETCH_AUTH_SUCCESS = 'FETCH_AUTH_SUCCESS' 
    export const FETCH_AUTH_FAILURE = 'FETCH_AUTH_FAILURE' 
    export const FETCH_AUTH_CLEAR = 'FETCH_AUTH_CLEAR' 

    export function authSuccess(response) { 
     return { 
     type: FETCH_AUTH_SUCCESS, 
     payload: response 
     } 
    } 

    export function authFail(response) { 
     return { 
     type: FETCH_AUTH_FAILURE, 
     payload: response 
     } 
    } 

export function authClear() { 
    return { 
    type: FETCH_AUTH_CLEAR, 
    payload: null 
    } 
} 


export function fetchAuthentication(data) { 

    let url = 'http://localhost:8080/login'; 

    return function (dispatch) {  
    //axios.post(url, data) 
    axios.get(url, { 
     params: data 
    }) 
     .then(function (response) { 
     console.log(response); 

     if(response.data.status === "success"){ 
     dispatch(authSuccess(response)); 
     } 
     else{ 
     // fail - user not found for example 
     dispatch(authFail(response)); 
     } 

     }) 
     .catch(function (error) { 
     //console.log(error); 
     dispatch(authFail(error)); 
     }); 
    } 
} 


export function clearAuthentication() { 

    let url = 'http://localhost:8080/logout'; 

    return function (dispatch) {  
    //axios.post(url, data) 
    axios.get(url) 
    .then(function (response) { 
     console.log(response); 

     if(response.data.status === "success"){ 
     dispatch(authClear(response)); 
     } 
     else{ 
     // fail - user not found for example 
     dispatch(authFail(response)); 
     } 

    }) 
    .catch(function (error) { 
     //console.log(error); 
     dispatch(authFail(error)); 
    }); 
    } 
} 

//authReducer.js

次のようになります
import { FETCH_AUTH_SUCCESS, FETCH_AUTH_FAILURE, FETCH_AUTH_CLEAR } from '../actions/authAction' 

export function authReducer (state = {}, action) { 
    //console.log('reducer act', action) 
    switch (action.type) { 
    case FETCH_AUTH_SUCCESS: 
     return {...state, data: action.payload, isLogged: true}; 
    case FETCH_AUTH_FAILURE: 
     return {...state, data: action.payload, isLogged: false}; 
    case FETCH_AUTH_CLEAR: 
     return {...state, data: action.payload, isLogged: false}; 
    default: 
     return {...state} 
    } 
} 

「スティーブン・ダニエル・アンダーソン」の回答

"

const user = localStorage.getItem('user') 
if(user){ 
    //Set the state authenticated to true; 
    store.dispatch({ 
     type:AUTH_USER 
    }) 
} 

"

より

const user = localStorage.getItem('user') 
if(user){ 
    //Set the state authenticated to true; 
    authSuccess(user) 
} 

や自分の行動のようなものになるユーザチェックでこの

export function fetchResumeAuth(data) { 
    dispatch(authSuccess(data)); 
} 

、その後のような新しい機能を作成します - - これはrouter.jsに置かれますか?

localStorage.setItem('user',user)あなたのアクションの作成者の内部でログの中で:あなたは、ブラウザでユーザーを保存するためのlocalStorageを使用することができます

const user = localStorage.getItem('user') 
if(user){ 
    //Set the state authenticated to true; 
    fetchResumeAuth(user) 
} 
+0

そのウェブアプリ - 私は 'Reduxの、持続/ストレージ' –

+0

CONST persistor = persistStore(店舗、{ストレージから 'Reduxの、持続' インポート{asyncSessionStorage}からこの インポート{persistStore、autoRehydrate}を追加しました:asyncSessionStorage}、()=> { console.log( 'restored'); } –

+0

https://stackoverflow.com/questions/41566866/save-and-retrieve-states-with-redux-persist-react - ネイティブ –

答えて

0

それからちょうどでない場合、ユーザーは次のように、偽oを認証されている場合はtrueに状態を設定減速作成:

import { AUTH_USER, UNAUTH_USER, ERROR } from '../actions/types' 

export default function (state={}, action){ 
    switch(action.type){ 
     case AUTH_USER: 
      return { ...state, authenticated: true } 
     case UNAUTH_USER: 
      return { ...state, authenticated: false } 
     default: 
      return state 
    } 

} 

そして、最後の部分をユーザーがするたびに認証された場合に検証されますindex.jsファイルで、ページをリロードします。

const user = localStorage.getItem('user') 
if(user){ 
    //Set the state authenticated to true; 
    store.dispatch({ 
     type:AUTH_USER 
    }) 
} 

注:あなただけの任意のビューでlocalStorage.getItem('user')を使用して、ユーザーにアクセスすることができます。

+0

あなたはコードリーダにいますか? @Steven Daniel Anderson - Authを処理するためのアクション設定があります - 私は自分のアクション機能を呼び出すと思います - 私の投稿を更新しましょう –

+0

authAction.jsを表示しながら私の質問を更新しました - - @スティーブンダニエルアンダーソン –

+0

または私のアクションで私はちょうど新しい機能を作成するだろう - それはディスパッチ?エクスポート関数fetchResumeAuth(data){dispatch(authSuccess(data));} –

関連する問題