My web app has both authenticated and unauthenticated parts. I need to know if there is a valid persistent authenticated login to decide whether or not to show the authorized UI when the app is first loaded. How do I get this state without doing anything in the UI?
Probably Auth.currentAuthenticatedUser() or Auth.currentSession(), but how do I tell if the user is the authenticated or unauthenticated role on the pool? I need to know if there is a persistent login to the authenticated role.
---- I just tried this when logged out
Auth.currentAuthenticatedUser()
.then(user => console.log(user))
.catch(err => console.log(err));
Died on Auth.js line 364, can't get Session on null.
Does there need to be Auth.currentAuthenticatedSession() to differentiate between sessions using the authenticated and unauthenticated roles?
I think what I need is to register a callback with Auth that gets called back on state change.
I have this complex mess currently...
class App extends Component {
handleAuthState(state) {
this.setState({ authState: state });
console.log("handleAuthState " + state);
}
constructor(props) {
super(props);
this.stateChange = this.handleAuthState.bind(this);
Auth.currentSession()
.then(user => this.stateChange('signedIn'))
.catch(err => this.state = {authState: 'signIn'});
this.state = {authState: 'signIn'};
}
render() {
return (
<Route
render={({ location }) => (
<NavigationDrawer
drawerTitle="Digispeaker"
toolbarTitle="Welcome to Digispeaker"
navItems={
(this.state.authState !== 'signedIn') ?
navItems.map(props => (<NavLink {...props} key={props.to} />)) :
navItemsAuth.map(props => (<NavLink {...props} key={props.to} />))
}
>
<Switch key={location.key}>
<Route exact path="/" location={location} component={Home} />
<Route path="/page-1" location={location} component={Page1} />
<Route path="/page-2" location={location} component={Page2} />
<Route path="/page-3" location={location} component={Page3} />
<Route path='/signon' render={(props) => (
<Signon handleAuthState={this.stateChange} {...props} />
)} />
</Switch>
export default class Signon extends Component {
handleAuthStateChange(state) {
this.props.handleAuthState(state);
}
render() {
return (
<Authenticator onStateChange={this.handleAuthStateChange.bind(this)}>
</Authenticator>
);
}
}
Signon.propTypes = {
handleAuthState: PropTypes.func,
};
I discovered Hub and rewrote to use it. This is a better solution, but... there is no event generated when the persisted login is applied.
Flow like this..
in constructor -> this.state = {authState: 'signIn'};
persistent login get evaluated down in Auth
Hub event -> this.state = {authState: 'signedIn};
now I display the correct UI
class App extends Component {
constructor(props) {
super(props);
this.state = {authState: 'signIn'};
Hub.listen('auth', this, 'stateChange');
}
onHubCapsule(capsule) {
debugger;
const { name, payload } = capsule;
if (name === 'auth') { this.setState({ authState: payload.event }); }
}
render() {
return (
<Route
render={({ location }) => (
<NavigationDrawer
drawerTitle="Digispeaker"
toolbarTitle="Welcome to Digispeaker"
navItems={
this.state.authState !== 'signedIn'
? navItems.map(props => <NavLink {...props} key={props.to} />)
: navItemsAuth.map(props => (
<NavLink {...props} key={props.to} />
))
}
>
<Switch key={location.key}>
<Route exact path="/" location={location} component={Home} />
<Route path="/page-1" location={location} component={Page1} />
<Route path="/page-2" location={location} component={Page2} />
<Route path="/page-3" location={location} component={Page3} />
<Route path="/signon" location={location} component={Signon}
/>
</Switch>
The recommended way right now is the way you did at the beginning.
Auth.currentAuthenticatedUser()
.then(user => console.log(user))
.catch(err => console.log(err));
What you saw is a bug. We just made a fix.
Thanks,
Richard
This code appears to work. I will switch onto currentAuthenticatedUser() from getSession() after the fix propagates into npm. Note that I needed to add bind() in a few places. The hub example needs to include this. Hopefully you will come up with a cleaner way to do this.
class App extends Component {
constructor(props) {
super(props);
this.stateChange = this.handleAuthState.bind(this);
Auth.currentSession()
.then(user => this.stateChange('signIn'))
.catch(err => this.stateChange('signOut'));
this.state = {authState: 'signOut'};
Hub.listen('auth', this, 'stateChange');
}
handleAuthState(state) {
this.setState({ authState: state });
}
onHubCapsule(capsule) {
const { channel, payload } = capsule;
if (channel === 'auth') {
this.stateChange(payload.event);
}
}
render() {
return (
<Route
render={({ location }) => (
<NavigationDrawer
drawerTitle="Digispeaker"
toolbarTitle="Welcome to Digispeaker"
navItems={
this.state.authState !== 'signIn'
? navItems.map(props => <NavLink {...props} key={props.to} />)
: navItemsAuth.map(props => (
<NavLink {...props} key={props.to} />
))
}
As the documentation is not clear, I would like to comment/ask here.
My intention is to find out if current user is authenticated or not. To minimize the amount of data which is coming from Cognito as well as to access to user attributes, I would like to use the following
componentDidMount() {
Auth.currentUserInfo()
.then(currentAccount => {
this.setState({
currentAccount: currentAccount,
isAuthenticated: true,
isLoading: false
})
}).catch(error => {
this.setState({
authError: error,
currentAccount: {},
isAuthenticated: false,
isLoading: false
})
})
}
But reading @richardzcode comment, where he says the the recommended approach would be to use currentAuthenticatedUser, I would like to understand if currentUserInfo, currentSession, currentUserCredentials methods still return currently authenticated user details? Are they equivalent from setting the authenticated flag point of view?
Most helpful comment
As the documentation is not clear, I would like to comment/ask here.
My intention is to find out if current user is authenticated or not. To minimize the amount of data which is coming from Cognito as well as to access to user attributes, I would like to use the following
componentDidMount() { Auth.currentUserInfo() .then(currentAccount => { this.setState({ currentAccount: currentAccount, isAuthenticated: true, isLoading: false }) }).catch(error => { this.setState({ authError: error, currentAccount: {}, isAuthenticated: false, isLoading: false }) }) }But reading @richardzcode comment, where he says the the recommended approach would be to use currentAuthenticatedUser, I would like to understand if currentUserInfo, currentSession, currentUserCredentials methods still return currently authenticated user details? Are they equivalent from setting the authenticated flag point of view?