amplify-js: Documentation does not specify how to handle return from successful hosted UI authentication
Given a generic npx create-react-app . ; npm install aws-amplify-react app with the following App.js:
import React, { Component } from 'react';
import Amplify, { Auth } from 'aws-amplify';
import { withOAuth } from 'aws-amplify-react';
const awsconfig = {
Auth: {
identityPoolId: ***redacted***,
region: ***redacted***,
userPoolId: ***redacted***,
userPoolWebClientId: ***redacted***,
oauth: {
domain: ***redacted***,
scope: ['email', 'profile', 'openid', 'aws.cognito.signin.user.admin'],
redirectSignIn: 'http://localhost:3000/',
redirectSignOut: 'http://localhost:3000/',
responseType: 'code',
},
},
}
Amplify.configure(awsconfig)
class App extends Component {
state = { isAuthenticated: false, }
async componentDidMount () {
try {
const currentAuthenticatedUser = await Auth.currentAuthenticatedUser()
if (currentAuthenticatedUser) { this.setState({isAuthenticated: true}) }
else { this.setState({isAuthenticated: false}) }
}
catch (error) { this.setState({isAuthenticated: false}) }
}
render () {
let response = (
<button onClick={this.props.OAuthSignIn}>Log In</button>
)
if (this.state.isAuthenticated) {
response = (
<p>Logged In</p>
)
}
return (
<div className="App">
{response}
</div>
)
}
}
export default withOAuth(App)
Authentication is successful and the hosted UI redirects back to http://localhost:3000/?code=...
At this point, however, the Log In button is still displayed and isAuthenticated is still false, although the call to Auth.currentAuthenticatedUser() has been successful and the access, id and refresh tokens have been added to local storage.
Reloading the page changes the state of isAuthenticated to true and everything works as expected, although the ?code=... query parameter is still present in the url.
It would be of great help if the documentation provided a simple example like this illustrating the following:
- where and how in the lifecycle to handle the redirect from a successful hosted UI authentication without manually reloading
- how to strip the
codequery parameter without a manual redirect
I’m wondering also if there is some complete other aspect of this missing - like having to also listen to the auth events from Hub and then respond (btw the documentation on Hub seems extremely sparse)
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 18
- Comments: 28 (6 by maintainers)
@elorzafe I have the exact same problem! Been trying to find a solution for days now.
@powerful23 thanks for this - it does work - a few comments:
?code...from the url I added athis.props.history.push('/')incheckUser()although this seems like a hackisAuthenticatingso that we can load a spinner or something instead.I’m fairly new to React so it is quite possible I’m missing some obvious ways of doing things, but I would think if the Amplify React components were a bit more complete in dealing with these kind of things people could get up and running w/ Cognito much quicker (not insulting the team’s efforts at all, just an opinion on which way to go with things!).
We are having the same problem where our users see our login UI for a few seconds when they are redirected back from Cognito Hosted UI. @powerful23 Do you have any timeline about when the isAuthenticating event will be implemented?
@tunecrew I can answer the second question. I agree to add a state like
isAuthenticating. For example, we can dispatch anisAuthenticatingevent by the Hub module so you can check it every time the page is reloaded. We are also working on to add a loading page foraws-amplify-react.@jadbox How are you redirecting your app? The code returned by Cognito will be used to revoke another call to get you the tokens for Auth so if you redirect your app before this process gets completed then you won’t be signed in successfully.
@jadbox you can do
import { Hub } from '@aws-amplify/core@tunecrew Hi, I can answer your first question. You can use the
Hubcategory to listen on thesignInevent. For exxample:@uclaeamsavino thanks for you feedback. The reason why you need to listen on Hub events before calling
Auth.currentAuthenticatedUser()is that there is some async process happens when redirecting back from the Hosted UI Page. We want to make sure all those async processes get done before people asking whether they are logged in or not.The Hub module is just a very simple implementation for the local events subscription. We will improve that category in the future for more generic use. Unfortunately for now it doesn’t provide the method to unsubscribe the listener. Will create a story for that.
@jadbox I’ll try and go a gist w/ my code.
I am facing this exact same problem. Is there a way around it ?
I have one issue with this method. If I use it on my home page, then a user signs in later through a different page. The home page listener still fires and I get the warning about component not mounted:
Does anyone know how I can unsubscribe to this when my Home component unmounts? Thanks a lot.