React不会渲染Auth0 userinfo

时间:2018-03-17 09:49:06

标签: reactjs auth0

大家好我在我的ASP.NET React应用程序中使用Auth0来处理我的身份验证。我希望用户能够登录后再将其转到Auth0登录,然后使用令牌重定向回应用程序,使用componentDidMount呈现应用程序以获取用户信息并将其放在屏幕上。目前,只有刷新页面才会呈现信息。

这是我的routes.jsx

let auth = new Auth();

const handleAuthentication = (props:any) => {
  if (/access_token|id_token|error/.test(props.location.hash)) {
    auth.handleAuthentication(props);
  }
}

export const routes = 
  <Layout auth={auth}>
    <Route exact path='/' render={(props) => <Home />} />
    <Route path='/counter' render={(props) => <Counter {...props} />} />
    <Route path='/fetchdata' render={(props) => <FetchData {...props} />} />
    <Route path="/callback" render={props => {
      handleAuthentication(props);
      return <Callback {...props} />
    }} />
  </Layout>;

这是我的Layout.jsx,我尝试在componentDidMount上呈现用户信息:

export class Layout extends React.Component<LayoutProps, LayoutStates> {
  constructor(props: any) {
    super(props);
    this.state = {
      profile: null
    }
  }

  componentDidMount() {
    const { isAuthenticated, getProfile, userProfile } = this.props.auth;
    if (isAuthenticated()) {
      getProfile( (err: any, profile: any) => {
        this.setState({
          profile: profile
        })
      })
    }
  }

  public render() {
    const { profile } = this.state;
    return (
      <div className='container-fluid'>
        <div className='row'>
          <div className='col-sm-3'>
            <NavMenu auth={this.props.auth} />
          </div>
          <div className='col-sm-9'>
            <h1 style={{color: 'red'}}>{profile == null ? 'No User Found' : this.state.profile.name}</h1>
            {this.props.children}
          </div>
        </div>
      </div>);
  }
}

这是我的Auth.js服务:

export default class Auth {
  private _auth0 = new auth0.WebAuth({
    domain: 'my_client_domain',
    clientID: 'some_client_id',
    redirectUri: 'http://localhost:5000/callback',
    audience: 'http://localhost:5000/api/',
    responseType: 'token id_token',
    scope: 'openid profile'
  })

  userProfile: any;

  constructor() {
    this.login = this.login.bind(this);
    this.logout = this.logout.bind(this);
    this.handleAuthentication = this.handleAuthentication.bind(this);
    this.isAuthenticated = this.isAuthenticated.bind(this);
    this.getProfile = this.getProfile.bind(this);
  }

  handleAuthentication(props:any) {
    this._auth0.parseHash((err: any, authResult: any) => {
      if (authResult && authResult.accessToken && authResult.idToken) {
        this.setSession(authResult);
        props.history.replace('/');
      } else if (err) {
        props.history.replace('/');
        console.log(err);
        return err;
      }
    })
  }

  getProfile(cb: any) {
    if (this.isAuthenticated()) {
      const token = String(localStorage.getItem('access_token'));
      this._auth0.client.userInfo(token, (err, profile) => {
        if(profile) {
          this.userProfile = profile;
          cb(err,profile);
        } else {
          console.log(profile);
        }
      })
    }
  }

  setSession(authResult: any) {
    let expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());
    localStorage.setItem('access_token', authResult.accessToken);
    localStorage.setItem('id_token', authResult.idToken);
    localStorage.setItem('expires_at', expiresAt);
    history.replace('/');
  }

  logout() {
    localStorage.removeItem('access_token');
    localStorage.removeItem('id_token');
    localStorage.removeItem('expires_at');
    this.userProfile = null;
    history.replace('/');
  }

  login() {
    this._auth0.authorize();
  }

  isAuthenticated() {
    let expiresAt = JSON.parse(String(localStorage.getItem('expires_at')));
    return new Date().getTime() < expiresAt;
  }
}

感谢任何帮助。感谢。

1 个答案:

答案 0 :(得分:1)

要阐述Rei Dien的评论,您要做的是使用componentDidUpdate(您可能使用其他生命周期方法)而不是componentDidMount

componentDidUpdate() {
  const { isAuthenticated, getProfile, userProfile } = this.props.auth;
  if (isAuthenticated()) {
    getProfile( (err: any, profile: any) => {
      this.setState({
        profile: profile
      })
    })
  }
}

这样,当你的道具改变你的生命周期时,方法将会触发,你的组件将像你期望的那样呈现。根据您的应用程序流程以及用户是否可以在登录时直接访问此页面,您可能仍希望实现componentDidMount

也许是这样:

componentDidMount() {
  this.loadProfile();
}

componentDidUpdate() {
  this.loadProfile();
}

loadProfile() {
   const { isAuthenticated, getProfile, userProfile } = this.props.auth;
   if (isAuthenticated()) {
    getProfile( (err: any, profile: any) => {
      this.setState({
        profile: profile
      })
    })
  }
}