2016-07-23 90 views
0

我使用react和react-route進行身份驗證。 我的目標是:在菜單欄上react-route>登錄後重定向到請求的內容

  1. 登錄鏈接,用戶可以通過這個鏈接
  2. 登錄,如果用戶在隨後登錄我需要在頁面的頂部顯示不同的菜單結構
  3. 如果用戶刷新然後在瀏覽器的內容不同 菜單需要呈現,這取決於用戶 的狀態(登錄,或匿名用戶)
  4. 如果一個鏈接,是不公開的,然後登錄匿名用戶點擊表格需要自動顯示
  5. 需要
  6. 成功登錄過程後,用戶被重定向到所請求的內容

我的解決辦法工作正常(如果有人有興趣的話,我會在這裏發佈我的代碼)。 (5)。我有一個與我最後一個目標有關的問題,(5)。我不知道在圖層中發送原始請求的路徑信息的最佳做法是什麼。最初請求的路徑出現在App.js(Route)中。然後它需要傳遞給onEnter方法。如果它是一個匿名用戶,而不是所請求的路徑需要傳遞給顯示的Login組件,並且最終在成功登錄後需要對原始請求的路由進行重定向。

我的解決方案使用url參數將請求的原始路由信息傳遞給登錄組件。

這裏是我的代碼:

App.js

function requireAuth(nextState, replace) { 
    if (!auth.loggedIn()) 
     replace({ 
      pathname: '/login?route=' + nextState.location.pathname, 
      state: { nextPathname: nextState.location.pathname } 
     }) 
} 

ReactDom.render(
    <Router history={hashHistory} onUpdate={() => window.scrollTo(0, 0)}> 
     <Route path="/" component={MainLayout}> 
      <IndexRoute component={Home} /> 

      <Route path="login" component={Login} /> 
      <Route path="login?route=:route" component={Login} /> 

      <Route path="logout" component={Logout} /> 
      <Route path="about" component={About} /> 
      <Route path="profile" component={Profile} onEnter={requireAuth} /> 
     </Route> 
    </Router>, 
    document.getElementById('root') 
); 

Login.js

import React from 'react'; 

import { withRouter } from 'react-router'; 
import auth from '../auth/Auth'; 
import Button from "react-bootstrap/lib/Button"; 

export default class Login extends React.Component { 

    doRedirect() { 
     if (this.props.location.query.route) 
      this.props.router.push(this.props.location.query.route); 
     else 
      this.props.router.push('/'); 
    } 

    render() { 
     return (
      <div style={style.text}> 
       <h3>LOGIN FORM</h3> 
       <Button bsStyle="primary" onClick={() => auth.login("username", "password", this.doRedirect.bind(this))}> 
        Login 
       </Button> 
      </div> 
     ); 
    } 
} 

// wrap with the withRouter HoC to inject router to the props, instead of using context 
export default withRouter(Login); 

有沒有更好或更符合反應液通過請求的URI來登錄組件?

THX。

+0

只有一個改善我能做些什麼:更換({ 路徑: '/登錄', 查詢:{路線:nextState。location.pathname}, state:{nextPathname:nextState.location.pathname} }) – zappee

回答

0

我不知道反應符合的解決方案。但auth重定向處理它以不同的方式。在配置文件頁(認證用戶視圖內容)驗證路由中的身份驗證,而不是OnEnter。 透視給予匿名用戶在視圖中呈現不同信息的選項。

export default class ProfilePage extends React.Component { \t 
 
\t 
 
    constructor(props) { 
 
\t \t super(props) 
 
\t \t this.renderProfile=this.renderProfile.bind(this) 
 
\t \t this.renderAskToLogin=this.renderAskToLogin.bind(this) 
 
\t \t this.handleOnLoginBtnTap = this.handleOnLoginBtnTap.bind(this); 
 
\t \t this.getProfiles = this.getProfiles.bind(this); 
 
\t \t this.reloadProfiles =this.reloadProfiles.bind(this); 
 
\t \t this.state = { 
 
\t \t Profiles: ProfileStore.getAll() 
 
\t \t }; 
 
    } \t 
 
    
 
    
 
    handleOnLoginBtnTap(){ 
 
\t \t this.context.router.replace({ 
 
\t \t \t pathname: '/login', 
 
\t \t \t state: { nextPathname: '/Profile' } 
 
\t \t \t }) 
 
    } 
 
\t 
 
    render() { 
 
\t const { loginId, authenticated} = Auth.loggedIn() 
 
\t return ( 
 
\t \t \t <div> 
 
\t \t \t \t {authenticated? this.renderProfile() : this.renderAskToLogin()} 
 
\t \t \t </div> 
 
\t \t) 
 
    } 
 
    
 
    
 
renderProfile() { 
 
\t \t const { Profiles } = this.state; 
 

 
\t \t const ProfileComponents = Profiles.map((Profile) => { 
 
\t \t \t return <Profile key={Profile.name} {...Profile}/>; 
 
\t \t }); 
 
\t 
 
\t \t return (
 
\t \t \t \t <div> 
 
\t \t \t \t <h4> Welcome to <b>ProfileGroup</b> </h4> \t \t \t \t 
 
\t \t \t \t \t <button onClick={this.reloadProfiles}>Refresh!</button> 
 
\t \t \t \t \t <h1> Profile List</h1> 
 
\t \t \t \t \t <ul>{ProfileComponents}</ul> 
 
\t \t \t \t </div> 
 
\t \t) 
 
    } 
 
    
 
    renderAskToLogin() { 
 
    return (
 
\t \t \t <div> 
 
\t \t \t <h4 className='red-txt'>Welcome to <b>Profile Group</b>.You are not yet authendicated. \t </h4> 
 
\t \t \t <h4> If you want to login, please tap Login button</h4> 
 
\t \t \t <button ref='loginBtn' className="btn btn-primary" onClick={this.handleOnLoginBtnTap}> Log In</button> 
 
\t \t \t </div> 
 
    ) 
 
    } 
 
    
 
} 
 

 
ProfilePage.contextTypes = { 
 
\t \t router: React.PropTypes.object.isRequired 
 
\t }

+0

Thx爲答案。我非常喜歡你的概念。我使用相同的方法呈現我的菜單內容:if(auth.loggedIn())返回其他。老實說,我不知道爲什麼我混合使用onEnter()方法和這種方法。也許是因爲我在這個主題中發現的文章只是建議使用onEnter()。當我編寫我的菜單組件時,我還沒有閱讀過任何文章:)我將從我的路線中刪除onEnter。無論如何,最初的問題呢?你有什麼解決方案嗎? – zappee

0

按我的代碼,在ProfilePage handleOnLoginButton(),當用戶點擊登錄解僱。在該處理程序中,將下一個路徑設置爲當前頁面並重定向到登錄頁面。 在loginpage中,成功登錄後handleOnLoginBtnTap()事件句柄重定向到狀態中存在的下一個路徑。

//Login Page 
 
handleOnLoginBtnTap(){ 
 
\t \t \t \t console.log("Login validation in progress ..") 
 
\t \t \t \t Auth.login(this.state.loginId, this.state.loginPwd, (loggedIn) => { 
 
\t \t \t \t \t if (!loggedIn) 
 
\t \t \t \t \t { 
 
\t \t \t \t \t \t alert("Login Validation failed. login Id and password should be same"); 
 
\t \t \t \t \t \t return; 
 
\t \t \t \t \t } 
 

 
\t \t \t \t \t const { location } = this.props 
 

 
\t \t \t \t \t if (location.state && location.state.nextPathname) { 
 
\t \t \t \t \t \t \t this.context.router.replace(location.state.nextPathname) 
 
\t \t \t \t \t } else { 
 
\t \t \t \t \t \t this.context.router.replace('/') 
 
\t \t \t \t \t } 
 
\t \t \t \t }) 
 
    }