大家好我在我的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;
}
}
感谢任何帮助。感谢。
答案 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
})
})
}
}