2017-09-25 55 views
0

我嘗試將用戶重新路由到用戶試圖在瀏覽器地址欄上導航的url: 我檢查用戶是否登錄調用服務方法。如果cookie中的會話過期或無效,則返回401個狀態,我會重定向到登錄界面React組件渲染不是第一次用redux

  1. 如果用戶已登錄,允許。

  2. 如果用戶沒有登錄,路線登錄畫面和登錄後,路線所需的URL。

這裏的問題是,當用戶鍵入一個網址,如:http://url/app/order 它被重定向到登錄網址:http://url/auth/login 用戶後進入了他的證件,雖然動作被分派,渲染爲Authorizedroute組件不被調用。我再次點擊登錄按鈕後,它被調用。

以下是我的登錄組件

export class LoginForm extends React.Component { 

componentWillReceiveProps(newProps){ 

    const { location, isAuthenticated, history } = newProps; 
    if(isAuthenticated){ 

     if(location.state && location.state.referrer){ 
      history.push(location.state.referrer.pathname); 
     }else{ 
      history.replace('/app'); 
     } 
    } 
} 

render() { 
    let usernameInput, passwordInput; 
    const { showErrorMessage, errorMessage, onLogin } = this.props; 
    return (


     <div className='sme-login-center-view-container'> 
      <HeaderComponent /> 

      <Col lg={4} lgOffset={4} sm={12} xs={12}> 
       <Col lg={10} lgOffset={2} sm={4} smOffset={4}> 
        <Form className="sme-login-box" onSubmit={(e)=> { 
                 e.preventDefault(); 
                 let creds = {username: usernameInput.value, password: passwordInput.value}; 
                 onLogin(creds);            
                } 
               }> 

          <span className='text-center sme-login-title-text'><h4>User Login</h4></span> 

         <FormGroup >      
          {errorMessage ? (<Alert bsStyle="danger"><strong>Error!</strong> {errorMessage}</Alert>) : null } 
         </FormGroup> 

         <FormGroup controlId="formHorizontalUsername">      
          <FormControl type="username" placeholder="Username" bsStyle="form-rounded" 
           inputRef={(ref) => {usernameInput = ref}} 
          />     
          <FormControl.Feedback> 
           <span className="fa fa-user-o sme-login-input-feedback-span"></span> 
          </FormControl.Feedback>    
         </FormGroup> 

         <FormGroup controlId="formHorizontalPassword">     
          <FormControl type="password" placeholder="Password" 
           inputRef={(ref) => {passwordInput = ref}}/>         
          <FormControl.Feedback> 
           <span className="fa fa-lock sme-login-input-feedback-span"></span> 
          </FormControl.Feedback> 
         </FormGroup> 

         <FormGroup>    
          <Button type="submit" block >Login</Button>    
         </FormGroup> 

        </Form> 
       </Col> 
      </Col> 
     </div> 

    ); 
} 
} 

LoginContainer

const mapStateToProps = state => { 
    return state.authenticationReducer.login 
} 

export const Login = withRouter(connect(mapStateToProps,{ onLogin: loginUser })(LoginForm)) 

登錄行動

export function requestLogin(creds) { 
    return { 
    type: LOGIN_REQUEST, 
    isFetching: true,  
    isAuthenticated: false, 
    creds 
    } 
} 
export function receiveLogin() { 
    return { 
    type: LOGIN_SUCCESS, 
    isFetching: false, 
    isAuthenticated: true 
    } 
} 
export function loginError(message) { 
    return { 
    type: LOGIN_FAILURE, 
    isFetching: false, 
    isAuthenticated: false, 
    errorMessage: message 
    } 
} 
export function loginUser(creds) { 
    return dispatch => {  
    dispatch(requestLogin(creds))  
     return axios.post(url, data) 
      .then(response => { 
       if (!response.status === 200) {      
        dispatch(loginError(response.statusText))      
       } else { 
        dispatch(receiveLogin()) 
       } 
      } 
     ).catch(function (error) { 
      dispatch(loginError(error.response.statusText)) 
     } 
    ) } 
    } 

登錄減速機:

export function login(state = { 
     isFetching: false, 
     isAuthenticated: false 
     }, action) { 

     switch (action.type) { 
     case LOGIN_REQUEST: 
     case LOGIN_SUCCESS: 
     case LOGIN_FAILURE: 
      return Object.assign({}, state, action) 
     default: 
      return state 
     } 
    } 

授權路由組件

class AuthorizedRouteComponent extends React.Component { 

    componentWillMount() { 
    this.props.getUser(); 
    } 
    render() { 
    const { component: Component, pending, logged, location, ...rest } = this.props; 
    return (
     <Route {...rest} render={props => { 
     if (pending) return <div>Loading...</div> 
      return logged 
       ? <Component {...this.props} /> 
       :<Redirect to={{ 
        pathname: '/auth/login', 
        state: { referrer: location } 
      }}/> 
      }} /> 
     ) 
     } 
    } 

    const mapStateToProps = state => { 
     return state.authenticationReducer.loggedUser 
    } 

    const AuthorizedRoute = connect(mapStateToProps, { getUser: getLoggedUser })(AuthorizedRouteComponent); 

    export default AuthorizedRoute 

查找登錄的用戶動作

export function requestFetch() { 
    return { 
    type: FETCH_REQUEST,  
    pending: true,  
    logged: false 
    } 
} 
export function receiveFetch(userData) { 
    return { 
    type: FETCH_SUCCESS, 
    pending: false, 
    logged: true, 
    userData 
    } 
} 
export function fetchError(message) { 
    return { 
    type: FETCH_FAILURE, 
    pending: false, 
    logged: false, 
    errorMessage:message 
    } 
} 
export function getLoggedUser() { 
    return dispatch => {  
    dispatch(requestFetch()) 
    return axios.get('/o3/rest/user/userdetails') 
      .then(response => { 

       if (!response.status === 200) { 
        dispatch(fetchError(response.statusText))     
       } else { 
        dispatch(receiveFetch(response.data)) 
       } 
      } 
     ).catch(function (error) { 
      dispatch(fetchError(error.response.statusText)) 
      } 
     ) 
    } 
} 

最後我登錄的用戶減速器

export function loggedUser(state = initialState, action) { 
    switch (action.type) { 
    case FETCH_REQUEST: 
    case FETCH_SUCCESS: 
    case FETCH_FAILURE: 
     let obj = Object.assign({}, state, action); 
     return obj; 
    default: 
     return state 
    } 
} 

回答

0

您可以使用localStorage的保存用戶在你的行動的創建者是收費獲取的用戶:

export function getLoggedUser() { 
    return dispatch => {  
    dispatch(requestFetch()) 
    return axios.get('/o3/rest/user/userdetails') 
      .then(response => { 

       if (!response.status === 200) { 
        dispatch(fetchError(response.statusText))     
       } else { 
        localStorage.setItem('userData',response.data) 
       } 
      } 
     ).catch(function (error) { 
      dispatch(fetchError(error.response.statusText)) 
      } 
     ) 
    } 
} 

然後在在索引文件問:

const userData = localStorage.getItem('userData') 
if(userData){ 
    store.dispatch({ 
     type: FETCH_SUCCESS, 
     pending: false, 
     logged: true, 
     userData 
    }) 
} 

每次刷新頁面或只需鍵入像http://url/app/order一個URL是要驗證時間是存在當前登錄用戶,是否存在將派遣一個動作更新你的狀態。

+0

的用戶數據服務被調用一次刷新瀏覽器,我不希望把它在localStorage的,因爲瀏覽器被刷新時,我不希望用戶看到任何東西,如果會話過期o是無效的時候。反正我在我的崗位問題是,爲什麼AutjorizedRoute組件的渲染方法不叫登陸之後的第一時間,而是再次點擊登錄按鈕時的作品。 – Fadd