Describe the bug
I am following the link :
https://aws-amplify.github.io/docs/js/authentication#oauth-and-hosted-ui
Section: OAuth and Hosted UI
Methods for facebook:
The sad state of amplify is there is no where in documentation it talked about redirection URI and everywhere it talked about using withAuthenticator HOC component.
I end up spending days to solve small issues with Amplify. It is just a request if someone from Amplify team look into the issue quickly and have documents up to date. There were many similar issues in the forum without resolution and they were closed.
One such reference is here: federated logins in react-native examples #3302
It would be very helpful if someone can tell what would be the exact redirection URL one should put while authenticating federated identities.
I always get this error: with redirectionURL set to: "com.dahersoftware.skillmgt://" (My app name)
https://
While doing Amplify.configure I override redirectionURL values and it never works. It works for my react app though.
It would be very helpful if someone can tell what would be the exact redirection URL one should put while authenticating federated identities.
Are you trying to use Federated Identities instead of User Pools? If so then you'll need to use the overloaded method of Auth.federatedSignin with a token as outlined here: https://aws-amplify.github.io/docs/js/authentication#identity-pool-federation
@undefobj We are using Cognito User Pools and has enabled federated facebook and google while setting up amplify using amplify add auth
As per the below document link
https://aws-amplify.github.io/docs/js/authentication
Social Provider Federation
Many apps also support login with a social provider such as Facebook, Google Sign-In, or Login With Amazon. The preferred way to do this is via an OAuth redirect which lets users login using their social media account and a corresponding user is created in User Pools. With this design you do not need to include an SDK for the social provider in your app. Set this up by running amplify add auth and selecting the social provider option. Upon completion you can use Auth.federatedSignIn() in your application to either show a pre-built “Hosted UI” or pass in a provider name (e.g. Auth.federatedSignIn({provider: 'Facebook'})) to interface directly and build out your own UI.
@undefobj To add more info.. We tapped the redirection request from mobile
https://
Somehow redirection_uri is not right but where we should do it there is no help regarding that.
As I said earlier we are using Cognito user pool and same user pool we are using for react app and everything works fine there.
Have the same challenges as @dahersoftware. React native with hooks + expo + Amplify for Cognito user pools using federated auth with facebook/google. No need for Cognito federated identities.
For react it's easy to use Amplify to authenticate via Facebook/Google, for react native extremely challenging (and probably it never worked). Documentation: i do really appreciate hard work all of you here, but still it's is a mess - takes a lot of time to even understand what is and what is not supported.
I use the following code:
export default function App() {
const [user, setUser] = useState('');
const [isLoggedIn, setIsLoggedIn] = useState(false)
useEffect(() => {
Hub.listen("auth", ({ payload: { event, data } }) => {
switch (event) {
case "signIn":
setUser(data);
setIsLoggedIn(true);
console.log("User logged in: ", data);
break;
case "signOut":
setUser('');
setIsLoggedIn(false);
console.log("User logged out: ", data);
break;
case "customOAuthState":
setUser(data);
}
});
}, []); //call Hub listen only on component mount & unmount
return (
<React.Fragment>
{isLoggedIn ? <Text>User logged in as {user.username}</Text>:
<View style={styles.container2}>
<Button title="FacebookSignIn" onPress={() => { Auth.federatedSignIn({ provider: 'Facebook' }); }} />
<Button title="GoogleSignIn" onPress={() => { Auth.federatedSignIn({ provider: 'Google' }); }} />
<Button title="HostedUISignIn" onPress={() => { Auth.federatedSignIn(); }} />
<Button title="SignOut" onPress={() => { Auth.signOut(); }} />
</View>
}
</React.Fragment>
);
}
in my aws-exports config:
const awsmobile = {
"aws_project_region": "eu-central-1",
"aws_cognito_identity_pool_id": "eu-central-1:de11aea1-6ca6-4f74-9953-97b0fxxxxx",
"aws_cognito_region": "eu-central-1",
"aws_user_pools_id": "eu-central-1_lJxxxxx",
"aws_user_pools_web_client_id": "xxxxx",
"oauth": {
"domain": "project3310eb456-310eb456-project.auth.eu-central-1.amazoncognito.com",
"scope": [
"phone",
"email",
"openid",
"profile",
"aws.cognito.signin.user.admin"
],
"redirectSignIn": "exp://127.0.0.1:19000/--/",
"redirectSignOut": "exp://127.0.0.1:19000/--/",
"responseType": "code"
},
"federationTarget": "COGNITO_USER_POOLS"
};
Versions:
"aws-amplify": "^1.2.3",
"aws-amplify-react-native": "^2.2.3",
"expo": "^35.0.0",
"react": "16.8.3",
Now in apple IOS simulator i am redirected, authenticate with facebook and get redirected back to my app, it's rendered correctly - user name is displayed - but it somehow hangs after that, still troubleshooting.
In Android 10 simulator once i authenticate with facebook and get redirected i got error:
console.error: "[ERROR] 30:55.468 OAuth - Error handling auth response.", {"line":182049,"column":32,"sourceURL":"http://127.0.0.1:19001/node_modules/expo/AppEntry.bundle?platform=android&dev=true&minify=false&hot=false"}
__expoConsoleLog
RemoteConsole.js:80:37
[ERROR] 30:55.468 OAuth - Error handling auth response., [Error: invalid_grant]
[Unhandled promise rejection: TypeError: undefined is not an object (evaluating '_a.accessToken')]
When i repeat the same steps using Google authentication i got identical error for both IOS + Android simulator. The same error when choosing HostedUI page (which is interesting because i got this error for IOS simulator when using hostedIU + facebook while i do not get any error and redirection back works fine for IOS simulator and direct facebook).
Would be great to have posted a simple react-native app using hooks with working facebook/google auth - it seems everybody is still struggling with it. Again: the documentation for react vs react native should be splitted IMHO.
Thanks,
@undefobj Any update on this.
just a side note, since this part of Amplify code seems to be broken (or i am unable to use it correctly) i have started to use expo:
Facebook.logInWithReadPermissionsAsync()
Google.logInAsync()
And after that i use Amplify:
Auth.federatedSignIn() with facebook token
new AWS.CognitoIdentityCredentials with google token (i have multiple app id and need to use openconnect id with identity pools and that does not seem to be supported by Amplify)
Not everything yet works for me, but i have some progress, will post working code once i have it.
@michalgarcarz expo is okay but we don't use expo and as u said u still don't have working solution.
I am hoping someone put some helping hand here.
@undefobj is there any way I can receive quick help for this issue. My application deployment is blocked because of this. Any workaround for now.
Have the same challenges as @dahersoftware. React native with hooks + expo + Amplify for Cognito user pools using federated auth with facebook/google. No need for Cognito federated identities.
For react it's easy to use Amplify to authenticate via Facebook/Google, for react native extremely challenging (and probably it never worked). Documentation: i do really appreciate hard work all of you here, but still it's is a mess - takes a lot of time to even understand what is and what is not supported.
I use the following code:
export default function App() { const [user, setUser] = useState(''); const [isLoggedIn, setIsLoggedIn] = useState(false) useEffect(() => { Hub.listen("auth", ({ payload: { event, data } }) => { switch (event) { case "signIn": setUser(data); setIsLoggedIn(true); console.log("User logged in: ", data); break; case "signOut": setUser(''); setIsLoggedIn(false); console.log("User logged out: ", data); break; case "customOAuthState": setUser(data); } }); }, []); //call Hub listen only on component mount & unmount return ( <React.Fragment> {isLoggedIn ? <Text>User logged in as {user.username}</Text>: <View style={styles.container2}> <Button title="FacebookSignIn" onPress={() => { Auth.federatedSignIn({ provider: 'Facebook' }); }} /> <Button title="GoogleSignIn" onPress={() => { Auth.federatedSignIn({ provider: 'Google' }); }} /> <Button title="HostedUISignIn" onPress={() => { Auth.federatedSignIn(); }} /> <Button title="SignOut" onPress={() => { Auth.signOut(); }} /> </View> } </React.Fragment> ); }in my aws-exports config:
const awsmobile = { "aws_project_region": "eu-central-1", "aws_cognito_identity_pool_id": "eu-central-1:de11aea1-6ca6-4f74-9953-97b0fxxxxx", "aws_cognito_region": "eu-central-1", "aws_user_pools_id": "eu-central-1_lJxxxxx", "aws_user_pools_web_client_id": "xxxxx", "oauth": { "domain": "project3310eb456-310eb456-project.auth.eu-central-1.amazoncognito.com", "scope": [ "phone", "email", "openid", "profile", "aws.cognito.signin.user.admin" ], "redirectSignIn": "exp://127.0.0.1:19000/--/", "redirectSignOut": "exp://127.0.0.1:19000/--/", "responseType": "code" }, "federationTarget": "COGNITO_USER_POOLS" };Versions:
"aws-amplify": "^1.2.3",
"aws-amplify-react-native": "^2.2.3",
"expo": "^35.0.0",
"react": "16.8.3",Now in apple IOS simulator i am redirected, authenticate with facebook and get redirected back to my app, it's rendered correctly - user name is displayed - but it somehow hangs after that, still troubleshooting.
In Android 10 simulator once i authenticate with facebook and get redirected i got error:console.error: "[ERROR] 30:55.468 OAuth - Error handling auth response.", {"line":182049,"column":32,"sourceURL":"http://127.0.0.1:19001/node_modules/expo/AppEntry.bundle?platform=android&dev=true&minify=false&hot=false"}
__expoConsoleLog
RemoteConsole.js:80:37[ERROR] 30:55.468 OAuth - Error handling auth response., [Error: invalid_grant]
- node_modules/expo/build/environment/muteWarnings.fx.js:27:24 in error
- ... 16 more stack frames from framework internals
[Unhandled promise rejection: TypeError: undefined is not an object (evaluating '_a.accessToken')]
- node_modules/@aws-amplify/auth/lib-esm/Auth.js:1655:57 in
- node_modules/@aws-amplify/auth/lib-esm/Auth.js:44:27 in step
- ... 12 more stack frames from framework internals
When i repeat the same steps using Google authentication i got identical error for both IOS + Android simulator. The same error when choosing HostedUI page (which is interesting because i got this error for IOS simulator when using hostedIU + facebook while i do not get any error and redirection back works fine for IOS simulator and direct facebook).
Would be great to have posted a simple react-native app using hooks with working facebook/google auth - it seems everybody is still struggling with it. Again: the documentation for react vs react native should be splitted IMHO.
Thanks,
I also facing same issue with react-native (android).
@dahersoftware did you get any workaround for this issue?
@undefobj any update?
@ni3galave no update from my side.
I think the main issue here is that in Expo, deep linking is built in (see exp:// in that aws-export there)...where as for @dahersoftware he is not using expo. @dahersoftware are you using some sort of deep linking handler in your React Native app using the Linking API in react native? See some details/tutorials that worked for us in testing:
Did you initialize your app with the Amplify CLI? It looks also like, based on this error message "error=redirect_mismatch" that your redirect url you are sending is not the one you have configured in Cognito User Pools. This setting is configured when you use the CLI and add auth with social provider. You will end up with a similar config presented above in the expo app, which Amplify will end up using internally. If you are not using the CLI, you'd need to send in the OAuth configuration to Amplify:
// App.js
import React, { Component } from 'react';
import './App.css';
import Amplify, { Auth } from 'aws-amplify';
import awsconfig from './aws-exports'; // your Amplify configuration
// your Cognito Hosted UI configuration
const oauth = {
domain: 'your_cognito_domain',
scope: ['phone', 'email', 'profile', 'openid', 'aws.cognito.signin.user.admin'],
redirectSignIn: 'myapp://oauth/',
redirectSignOut: 'myapp://signout/',
responseType: 'code' // or 'token', note that REFRESH token will only be generated when the responseType is code
};
Amplify.configure(awsconfig);
Auth.configure({ oauth }); // <-- here is where the oauth config is sent in.
This is outlined in the docs under "Full React Sample" here:
https://aws-amplify.github.io/docs/js/authentication#react-components
We will see if a docs update is required to better document this for React Native deep linking/redirects, especially around API as you stated, and specifically around configuration of OAuth, thanks for calling that out. For linking specifically this is referenced here: https://aws-amplify.github.io/docs/js/authentication#amplify-project-setup
The Android issue @ni3galave is experiencing there is something else, the Error: invalid_grant error is referring to token/code grant, which right now you have as "responseType": "code". Assuming that's what you have configured in your User Pool as well since it is working on iOS. I think this may be a permissions error on the Android side perhaps for Offline storage permission potentially?
See here:
https://stackoverflow.com/questions/10576386/invalid-grant-trying-to-get-oauth-token-from-google
Do you have this permission set on the Android side?
Thanks @mlabieniec for the update. I will check this as per your post and will update here if it works.
I'm facing this issue, with React-Native without Expo.
Following the example in the doc : https://aws-amplify.github.io/docs/js/authentication#facebook-example-in-react-native-expo, it seems that we need to get a token before launch the process with Auth.federatedSignIn() method.
Maybe a workaround would be to use react-native-fbsdk with the LoginManager.logInWithPermissions method which seems to be equal with the Facebook.logInWithReadPermissionsAsync() from Expo Facebook library.
@dahersoftware did you found a workaround ?
I'm using Expo and amplify to login via facebook using the federated login.
This works for me fine on my simulator but when I actually use on the device I can successfully 'Continue' using Facebook (web), but when it redirects back to expo I get an error:
"There was a problem loading the requested app"

In case anyone still needs help for expo+amplify+social logins
{
"expo": {
"scheme": "exposchemeappname://" // use any name you like, just make it unique
}
}
import { Linking } from 'expo';
import * as WebBrowser from 'expo-web-browser';
import awsconfig from './aws-exports';
const amplifyConfig = {
...awsconfig,
oauth: {
...awsconfig.oauth,
urlOpener: async (url, redirectUrl) => {
// On Expo, use WebBrowser.openAuthSessionAsync to open the Hosted UI pages.
const { type, url: newUrl } = await WebBrowser.openAuthSessionAsync(url, redirectUrl);
if (type === 'success') {
await WebBrowser.dismissBrowser();
if (Platform.OS === 'ios') {
return Linking.openURL(newUrl);
}
}
},
options: {
// Indicates if the data collection is enabled to support Cognito advanced security features. By default, this flag is set to true.
AdvancedSecurityDataCollectionFlag: true
},
}
};
const expoScheme = "exposchemeappname://"
// Technically you need to pass the correct redirectUrl to the web browser.
let redirectUrl = Linking.makeUrl();
if (redirectUrl.startsWith('exp://1')) {
// handle simulator(localhost) and device(Lan)
redirectUrl = redirectUrl + '/--/';
} else
if (redirectUrl === expoScheme) {
// dont do anything
} else {
// handle the expo client
redirectUrl = redirectUrl + '/'
}
amplifyConfig.oauth.redirectSignIn = redirectUrl;
amplifyConfig.oauth.redirectSignOut = redirectUrl;
Amplify.configure(amplifyConfig);
Make sure you add the following redirect urls to amplify amplify auth update
# development
exp://127.0.0.1:19000/--/
exp://192.168.1.101:19000/ # depends on your lan ip
# expo client
exp://exp.host/@[EXPO_ACCOUNT]/[EXPO_APPNAME]/
# expo scheme for standalone (Testflight)
exposchemeappname://
Thanks for this chunyenHuang - the use of localIP helped with the expo client on my device. I'm still struggling with the standalone app however. What should the redirect URL be for an app in TestFlight or the AppStore?
@JSDevelopment17
You will need to setup the scheme ( you can use any name you like)
// app.json
{
"expo": {
"scheme": "exposchemeappname://"
}
}
and use this
# expo scheme for standalone
exposchemeappname://
Apologies if this sounds dumb - where do I use the second bit? I've got app.json setup but it looks like I'm missing it from elsewhere
Apologies if this sounds dumb - where do I use the second bit? I've got app.json setup but it looks like I'm missing it from elsewhere
You need to run amplify auth update and add the new redirect url to your cognito service. And you should see the link in your aws-exports.json. Then you can use the script I provide here https://github.com/aws-amplify/amplify-js/issues/4244#issuecomment-586845322 to replace the redirectUrl from a string list to a single url string.
@JSDevelopment17 Hey man, i am struggling with the same issue for my android app using android studio, were you able to figure it out?
thanks
I'm also facing the same issue in react native both android and ios.
I've given redirect url as follows
redirectSignIn: 'myapp://',
redirectSignOut: 'myapp://',
@chunyenHuang thanks for your advice on the script; it worked really well to get the local expo instance working. I'm still having a problem getting my stand alone app to work with it. I am using facebook auth and it kicks back to my application but does not catch the auth and goes right back to the login page. My scheme is called fanscout:// and i tried adding fanscout://--/ to see if that would work but that just caused the redirect_mismatch error.
Is there something I need to add to catch the auth only for production? Sadly, because it's production / staging, it's the only place I can't debug.
I came across this, looking for something else, and thought I'd share the following, in case it might help someone.
Note that my app has a shared backend, in that both a web app and a React Native app use the same resources, including the user pool.
I'm also using multi-environments in amplify: dev, staging, & prod.
Expo
As this is an Expo app, let's start there with app.json. The key things in that file are:
{
"expo": {
...
"scheme": "myapp",
"name": "My App Dev",
"slug": "myapp-dev"
...
}
}
Note that I actually have one of these for each environment in addition to the app.json file: these are: app.dev.json, app.staging.json, app.prod.expo.json, and app.prod.standalone.json (I'll get to why later), and these differ, like:
{
"expo": {
...
"scheme": "myapp",
"name": "My App Staging",
"slug": "myapp-staging"
"splash": {
"image": "./assets/images/splash.png",
"resizeMode": "cover",
"backgroundColor": "#f8f9fa"
},
...
}
}
I also use different background colors on the splash screen to make it clear what environment I'm in.
Amplify
A similar approach is used with aws-exports.js (I'm using config, instead of exports below, but that doesn't matter here), in that I've got a file for each environment, with differing userpools and redirect URLs
Connecting the two
I use scripts in package.json to setup Amplify and Expo on start and publish. For example:
"scripts": {
"publishStaging": "cp app.staging.json app.json && cp aws-config.staging.js aws-config.js && expo publish",
"publishProd": "cp app.prod.standalone.json app.json && cp aws-config.prod.standalone.js aws-config.js && expo publish",
"publishExpo": "cp app.prod.expo.json app.json && cp aws-config.prod.expo.js aws-config.js && expo publish",
"start": "cp app.dev.json app.json && cp aws-config.dev.js aws-config.js && expo start",
"startStaging": "cp app.staging.json app.json && cp aws-config.staging.js aws-config.js && expo start",
"startExpo": "cp app.prod.expo.json app.json && cp aws-config.prod.expo.js aws-config.js && expo start",
"startProd": "cp app.prod.standalone.json app.json && cp aws-config.prod.standalone.js aws-config.js && expo start",
...
},
So something like npm run publishStaging will copy staging files to app.json and aws-exports.js and publish the expo app.
There are other, better ways (like doing this in CI) to do this, but this should serve as a decent example.
Redirect URLs
This assumes that you've already done the legwork to get the social stuff working for Apple, Amazon, Facebook, Google, etc.
The Redirect URLs need to setup in the User Pool, and each user pool (for each env) will have unique URLs.
In AWS Cognito => User Pools => App Client Settings:
*Callback URLS(s)
*Sign out URL(s)
Notes:
exp://exp.host/@kimfucious/myapp-staging uses the slug in app.jsonmyapp:// refers to the scheme in app.jsonAvoiding redirect_mismatch
Back in the app, in each of the aws-exports.ENV.js file, enter a single redirect URL.
dev, for example, would be:
const awsmobile = {
...
oauth: {
domain: "myapp-dev.auth.us-west-2.amazoncognito.com",
scope: [
"phone",
"email",
"openid",
"profile",
"aws.cognito.signin.user.admin"
],
redirectSignIn: "exp://192.168.1.116:19000/--/",
redirectSignOut: "exp://192.168.1.116:19000/--/",
responseType: "code"
},
...
};
And staging would be:
const awsmobile = {
...
oauth: {
domain: "myapp-staging.auth.us-west-2.amazoncognito.com",
scope: [
"phone",
"email",
"openid",
"profile",
"aws.cognito.signin.user.admin"
],
redirectSignIn: "exp://exp.host/@kimfucious/myapp-staging",
redirectSignOut: "exp://exp.host/@kimfucious/myapp-staging",
responseType: "code"
},
...
};
And prod would be:
const awsmobile = {
...
oauth: {
domain: "myapp-prod.auth.us-west-2.amazoncognito.com",
scope: [
"phone",
"email",
"openid",
"profile",
"aws.cognito.signin.user.admin"
],
redirectSignIn: "myapp://",
redirectSignOut: "myapp://",
responseType: "code"
},
...
};
I hope this helps 🌮
Thanks for the sharing !
I'm not using Expo, but thanks anyway !
@chunyenHuang @kimfucious I used same use case for RN & Expo as Amplify docs and your examples shows. I am trying this on dev, everything works fine (user signs in and getting user's pool credentials etc.) but then when I use Auth.signout(), sign out action works okey too (Hub.listener signout event triggers) but also urlOpener(code is below) triggers again with a permission request for redirectSignOut url. There is also an open issue about it #4993
urlOpener from Amplify docs:
async function urlOpener(url, redirectUrl) {
const { type, url: newUrl } = await WebBrowser.openAuthSessionAsync(
url,
redirectUrl
);
if (type === "success" && Platform.OS === "ios") {
WebBrowser.dismissBrowser();
return Linking.openURL(newUrl);
}
}
I use Auth.federatedsignin(Facebook, Google etc.) as an User Pool Federation like #2716 says and I expected just Auth.signout() should be enough. Why urlOpener is triggering again and requesting open webbrowser? I could prevent signout link's request but i am curious about why is it not being mentioned? Didn't you face this issue? This is a very basic use case, am I missing something?
I found the answer for my question #2115. Short answer is Amplify docs has poor quality, looking for this basic thing for a day or two.
The original issue in regards to the redirection URL mismatch error has been updated in our documentation site. You are able to find the full examples here. Resolving
I believe the solution to this problem has not been fixed yet. @sammartinez comment was a step in the right direction. However, I believe the problem is in url passed to open the facebook provider. See the following:
url passed to Auth.federatedSignIn() as seen through the openUrl() function --> https://myapp.auth.us-east-1.amazoncognito.com/oauth2/authorize?redirect_uri=myapp%3A%2F%2F&response_type=code&client_id=xxxxxxx&identity_provider=COGNITO&scope=email%20openid&state=xxxxxx&code_challenge=xxxx&code_challenge_method=xxx
as you can see, the redirect_uri parameter is myapp://. However, the "://" is encoded. I believe the encoding is causing the error that this thread is based on.
This is without using expo. I also have not yet determined a solution, but hopefully this is another step in the right direction.
Most helpful comment
Have the same challenges as @dahersoftware. React native with hooks + expo + Amplify for Cognito user pools using federated auth with facebook/google. No need for Cognito federated identities.
For react it's easy to use Amplify to authenticate via Facebook/Google, for react native extremely challenging (and probably it never worked). Documentation: i do really appreciate hard work all of you here, but still it's is a mess - takes a lot of time to even understand what is and what is not supported.
I use the following code:
in my aws-exports config:
Versions:
"aws-amplify": "^1.2.3",
"aws-amplify-react-native": "^2.2.3",
"expo": "^35.0.0",
"react": "16.8.3",
Now in apple IOS simulator i am redirected, authenticate with facebook and get redirected back to my app, it's rendered correctly - user name is displayed - but it somehow hangs after that, still troubleshooting.
In Android 10 simulator once i authenticate with facebook and get redirected i got error:
console.error: "[ERROR] 30:55.468 OAuth - Error handling auth response.", {"line":182049,"column":32,"sourceURL":"http://127.0.0.1:19001/node_modules/expo/AppEntry.bundle?platform=android&dev=true&minify=false&hot=false"}
__expoConsoleLog
RemoteConsole.js:80:37
[ERROR] 30:55.468 OAuth - Error handling auth response., [Error: invalid_grant]
[Unhandled promise rejection: TypeError: undefined is not an object (evaluating '_a.accessToken')]
When i repeat the same steps using Google authentication i got identical error for both IOS + Android simulator. The same error when choosing HostedUI page (which is interesting because i got this error for IOS simulator when using hostedIU + facebook while i do not get any error and redirection back works fine for IOS simulator and direct facebook).
Would be great to have posted a simple react-native app using hooks with working facebook/google auth - it seems everybody is still struggling with it. Again: the documentation for react vs react native should be splitted IMHO.
Thanks,