DEV Community

Cover image for The Complete React Native Guide to User Authentication with the Amplify Framework

The Complete React Native Guide to User Authentication with the Amplify Framework

Nader Dabit on December 02, 2019

In my previous post, The Complete Guide to User Authentication with the Amplify Framework, I walked through how to add username / password based au...
Collapse
 
antrobuss profile image
Steven Antrobus

Great article!
I've come across one problem that I just can't seem to resolve with Facebook login via FederatedIdentity - on my iOS simulator everything works great but when I run in the expo app (or push to TestFlight) the redirect back to the app from Facebook throws an error (attached). I'm not sure why I'm seeing a difference between the two. Any thoughts?
Thanks,
Steve.

Collapse
 
dabit3 profile image
Nader Dabit

Hey Steven, I'm sorry you're having that issue. Any way you can open an issue here and then we can escalate it or try to reproduce it / find a resolution?

Collapse
 
antrobuss profile image
Steven Antrobus

Done: Expo federated login redirect error #4800
(Thanks for the quick response)

Collapse
 
antrobuss profile image
Steven Antrobus

Hi Nader,

Did you have any luck with this? I can't seem to solve it on the device at all :'-(

Thanks,
Steve.

Collapse
 
nsanghi profile image
Nimish

Hi Nader,
I had used your article to setup a Facebook login for a mobile app and it has been working like a charm. Thanks for the detailed setup instructions.

Recently I got an alert from facebook that the facebook app that I created for social login is non complaint with URL policy as it is returning non compliant code. I had followed above instructions originally and checked once the latest amplify instructions at docs.amplify.aws/lib/auth/social/q....

If you refer to the instructions in article above for facebook configuration. It says....
"For the _Site URL), input the OAuth Endpoint URL with /oauth2/idpresponse appended into Site URL:"

This setup seems to be cause for the compliance issue. If I ping https://<your-user-pool-domain>/oauth2/idpresponse (using facebook's debug tool - developers.facebook.com/tools/debug)
, I get a response code 400. But if I ping https://<your-user-pool-domain> I get 200.

I am not sure if my production app will break if I change the url to just pool-domain without the extension /oauth2/idpresponse

Any pointers that you could suggest to meet facebook compliance.

Collapse
 
kimfucious profile image
Kim Ford

I keep coming back to this article, because it seems like the only one on the Internet that covers this topic in detail. That's the sign of a good post :)

Scenario: I'm using expo on an iPhone. I've implemented Sign in with Apple to the point now, where I can click on a button and I get swung out to appleid.apple.com page in Safari.

This opens an action menu for apple ID the first go round. And I click continue. Subsequent logins don't prompt with the action menu, as AppleID is already in use for the expo app.

I then get prompted to open Expo, because of the redirect (bad UX, but hey, I can't see a better way yet).

Now, I'm redirected to the page where I was last in my expo app.

If I use a React useEffect hook to run Auth.currentAuthenticatedUser() on page load, I get "not authenticated" as a response, after returning from appleId auth page.

If I shake the phone and reload the app, I become authenticated by my app (i.e. Auth.currentAuthenticatedUser() works just fine.

Question: I feel like I'm missing a crucial step here. What is it? :)

Collapse
 
kimfucious profile image
Kim Ford

I figured this out a while back... In short I was being a bit dumb...

The useEffect hook was worthless, because when the user is returned from to the app after successful authorization, they are not immediately recognized as being signed in, so an Auth.currentAuthenticatedUser() will throw an error.

One problem I had (still have) is it takes about 3 seconds after returning from the Auth provider to for the data.payload.event, signIn, to be "heard" by the hub. This delay only seems to occur on a mobile.

Anyhow, to provide better UX, I return the user to a page that has a, "Continue with" button, that sends them to a loading page until the signIn event occurs and I can trigger the app into action or handle an error from that point on.

Still way too many clicks and popping in/out of windows, which I'm thinking about how to reduce.

Collapse
 
ahmedmesawer profile image
Ahmed Mesawer • Edited

Please I need to help me with the following issue:
I get current credentials using Auth.currentUserCredentials() after calling Auth.currentAuthenticatedUser() and it refreshes token every time and that token remains valid for one hour and then it expires and gives me this error NotAuthorizedException: Invalid login token. Token expired how can I get a new token when it expires, thanks.

Collapse
 
flexbox profile image
David Leuliette 🤖 • Edited

Thanks @dabit3 for the article, I have a question tho.

Do you need to eject from expo to use this flow?

Because on one of my application I am using AsyncStorage to keep the user token.
But facebook/react-native is depprecated in flavor of @react-native-community/async-storage

I just wanted to know your opinion on this 😉

Collapse
 
danrivett profile image
Dan Rivett • Edited

Thanks for spending time to write this. My main question I have after trying this out, is that it came to my surprise that this flow boots you out of your app and into a web-browser.

This is not a great UX and so I was wondering if you or anyone knew how to integrate with AWS User Pools and Federated login using a native solution such as Expo's expo-google-sign-in or expo-facebook components such that the user doesn't get booted out the app into a browser window?

I'm very new to implementing federated sign-in on a native platform so apologies if it's obvious. If it's not possible, it definitely seems like a feature gap that should be considered.

Collapse
 
devusman profile image
Usman Suleiman

@dabit3 are these deprecated?

@aws_api_key - To specify the field is API_KEY authorized.

@aws_iam - To specify that the field is AWS_IAM authorized.

@aws_oidc - To specify that the field is OPENID_CONNECT authorized.

@aws_cognito_user_pools - To specify that the field is AMAZON_COGNITO_USER_POOLS authorized.
Collapse
 
dabit3 profile image
Nader Dabit

Hey, no you can still use these fields directly in the AppSync schema itself, without the GraphQL Transform library, to set authorization rules.

Collapse
 
devusman profile image
Usman Suleiman

Oh! Thanks. Now I get it.

Collapse
 
jaymmehta97_jay profile image
Jay Mehta • Edited

Great article!

I followed all the steps as defined here and everything works fine. The only issue that I get is about the app name in the sign in with apple sheet. When Apple presents the user with a consent sheet asking whether to hide email or share, the sheet's title is "Create an account for {App name} using your Apple ID". But in my case the sheet shows "Create an account for null using your Apple ID".

dev-to-uploads.s3.amazonaws.com/i/...

Another thing is that it always asks user whether to share or hide email even if the user has previously signed in. According to Apple docs user is only asked this for the first time and the preferred choice is persisted by Apple.

I do not face this issue when I try Apple login in Cognito's web hosted UI login.

My guess here is that Apple does not get my domain or bundle ID when presenting Sign in with Apple.

Can you please help me with this?

Thanks!

Collapse
 
vmadupu9 profile image
Varun Kumar Madupu

Hi Jay!! I am facing the same issue. If you have fixed this issue could you help me to fix the issue. It would be great if you provide some references. TIA!

Collapse
 
abattisson profile image
Andrew Battisson • Edited

Something that i came across after using this, I kept getting stuck on parsing callbackurl and the user never actually signing in once redirected back. I found the snippet below that i needed to add to my appdelegate.m, add the import at the top and the - (BOOL).. etc at the bottom

#import <React/RCTLinkingManager.h>

- (BOOL)application:(UIApplication *)application
   openURL:(NSURL *)url
   options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
  return [RCTLinkingManager application:application openURL:url options:options];
}
Collapse
 
puneetpandey10 profile image
puneet pandey

Hi Nader,

Please excuse me if my question sounds trivial to you. I am a just-started React-native developer. I am facing an issue with redirecting to the Google Auth page while I can successfully redirect to Facebook. But I am not much bothered about this issue as I believe it should only be a small mistake somewhere.

My main concern is about the redirect screens that seem to open up on web browser and NOT in the native Google and Facebook Apps. I would expect the Auth redirections to load the relevant pages on the native Apps. Can you please help me with this doubt as to why is it loading the screens over the browser? Wouldn't it be better if the Auth screens are opened up on the native Apps?

Collapse
 
puneetpandey10 profile image
puneet pandey

And why it matters to me is because a user would need to provide passwords even if he/she is already logged in to Google/Facebook in his/her mobile phone's native Apps. Please suggest! Thanks in advance!

Collapse
 
kris profile image
0xAirdropfarmer

This tutorial article is simply awesome. Thanks for this article. The stepwise guide explains a lot about integrating user authentication feature to a React Native app using React Native AWS Amplify. The guidance a lot with screenshots of code and configuration screens makes it easier to follow and understand.

Collapse
 
tanvivartak profile image
TanviVartak

Great Article! It helped me to configure Sign in With Apple using react native amplify + cognito.
But still I'm facing some issue. I use cognito user pool + federeted identity to create unique identities for your users and to securely access other AWS services.
After following your steps, user gets created in cognito user pool but Auth.currentAuthenticatedUser() returns unauthenticated user error. Also cred is undefined.
I have created issue github.com/aws-amplify/amplify-js/...
Any help is appreciated!

Collapse
 
avlonder profile image
avlonder

Hi Nader, many thanks for this very instructive article! How do I access the user object with Auth.currentAuthenticatedUser() right after the social login with Auth.federatedSignIn({provider})? Even though I use "await", I always get "not authenticated" unless I set a timer between the two calls.

Collapse
 
jerry_hopper profile image
jerry hopper

Awesome article, i have been struggling to get a decent reactnative app with authentication.
But after reading this, im going to try again using this guide in combination with FusionAuth.io as oauth provider.

Thx!

Collapse
 
edisonsanchez profile image
Edison Sanchez

Excellent, i try the article about the same Guide for React.js working perfect, but when I try to make a simple app in React native with the instructions, but i cant obtain the session token or code in the App.

The hub returns the error: undefined has parsingCallbackUrl

The flow of authentication go and returns its working, im testing on IphoneX simulator. Its showing a Message in Safari: "Open in "RNAmplify" (that's the name of my project). how i can void that open cycle?

Collapse
 
edisonsanchez profile image
Edison Sanchez

OK, i see my mistake, you have to enable Deep Linking on your IOS and Android. In order to avoid this situation could you update the Guide and include this when you said "XCode Configuration".

reactnative.dev/docs/linking

Collapse
 
kimfucious profile image
Kim Ford • Edited

Really nice write up. Thanks.

There's an interesting chicken/egg scenario I've discovered here if only wishing to implement Sign in With Apple, without the other providers.

In brief, as far as I can tell, you can't create (in my case, update) the auth in Amplify CLI without choosing one of the three available choices: Amazon, Facebook, & Google.

This results in the aws-export.js file not having any oauth info, which results in an error when using Auth with the federatedSignIn method: "Cannot read oauthSignIn of undefined".

'amplify pull' doesn't seem to bring down manual changes made in the User Pool, and adding anything manually to the aws-export.js file will get overwritten.

I guess, I could create/use a dummy setup with one of the three available to push this through, but I thought I'd ask if you/anyone had any thoughts first.

Collapse
 
kimfucious profile image
Kim Ford

Just a follow up to mention that I wound up adding google to amplify Auth, which ultimately populated the oauth section of the aws-exports.js file, which allowed me to move past this blocker.

Collapse
 
jsnavarroc profile image
Johan Navarro

Nader, Hey!! is it possible that the next guide is about how to make push notifications with amplify from 0 or connected it with this guide? Thanks again!!!

Collapse
 
seanrenet profile image
SeanRenet

HI Nader,

I think there is a typo in the Trying It Out section

Trying it out
Now, the project and the services are configured and we can start writing some JavaScript.

The first thing we need to do is configure the React Native Project to use the Amplify credentials. To do so, open aws-exports.js and add the following code:

import Amplify from 'aws-amplify'
import config from './aws-exports'
Amplify.configure(config)

I think that code should be added to App.js

In other news, still trying to catch you on Twitch

Collapse
 
fgyimah profile image
Francis Gyimah

Great article

Collapse
 
dabit3 profile image
Nader Dabit

Thanks!!

Collapse
 
lucky_girl_____ profile image
Iryna Kreichmann

When I'm creating Facebook app should I create only Web app? or Android and IOS apps as well?

Collapse
 
dabit3 profile image
Nader Dabit

You only need Web because we are using a WebView within the native iOS and Android app to do the redirect.

Collapse
 
snowleopardalex profile image
snowleopardAlex

Hi Nader! Thank you for the tutorial. I have one problem. When I click on the button Sign in with AppleID the hosted UI is displayed to me with the red warning at the top LOGIN OPTION IS NOT AVAILABLE. PLEASE TRY ANOTHER ONE. I configured AppleID as you said - in the apple developer, user pool. Do you have any idea why I am seeing this error? Thanks!

Collapse
 
gbaird profile image
Garrett Baird

Terrific article Nader! How to configure Sign in with Apple through withAuthenticator HOC? Not clear what exactly to pass into the federated attribute...

Collapse
 
mehdirazajaffri profile image
Mehdi Raza

also let me know when you got this

Collapse
 
arpecop profile image
Rudi

I can't seem to find auth url provided in the first steps my aws-config.js doesn't show them

Collapse
 
jsnavarroc profile image
Johan Navarro

Amaizing, really thanks!!

Collapse
 
sebastian_wirkert_59cfbb8 profile image
Sebastian Wirkert

Thank you so much. Have changed my app quite a bit over time (started with expo and amplify-cli, then kicked out both). Your article always had all the information needed at one place. Great work.

Collapse
 
kevins77794 profile image
Kevin Estrada

Hi Nader, would this also work if my backend is web api? Does it need some sort of configuration also in the backend? (react-native + web api)

Collapse
 
nilanjan2039 profile image
Nilanjan Mandal • Edited

Hey I've been trying to follow the guide but it doesn't seem to work for me on EXPO, It's giving "[ERROR] 31:10.583 OAuth - Error handling auth response., [Error: invalid_grant]"

Collapse
 
mehdirazajaffri profile image
Mehdi Raza • Edited

Cognito Hosted UI is not loading for me app opens the safari but UI doesn't load :( , tried opening the url in web that works fine there.