2016-07-23 94 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 }) 
 
    }