DEV Community

Cover image for Social authentication with AWS Amplify and React Native
Bastian Bavaresco
Bastian Bavaresco

Posted on

Social authentication with AWS Amplify and React Native

If you are struggling with social providers and you are trying to implement an OAuth flow, with AWS Amplify you can easily integrate one inside your app.

🔌 Getting started

First of all let's install the AWS Amplify CLI:
(inside the link you can also sign up for a free AWS account)

Requirements: Node.js version 8.x or greater and npm version 5.x

npm install -g @aws-amplify/cli

Now you can configure the CLI and setup your developing environment.
Follow the steps given by issuing this command:

amplify configure

💾 Install Expo and create our app

If you still don't know it Expo is a complete workflow that helps you build cross-platform native apps (React Native).
If you are planning to develop for iOS you need to work with a MacOS computer and install the latest version of Xcode.
If, on the other hand, your target is Android you need to install Android Studio.
Moreover, in case you need to develop a complete cross-platform app, you can use both tools. Once installed, these tools provide emulators that simulate iOS or Android systems.
Let's install the CLI:

npm install expo-cli --global

Then we can create our project, install some packages and finally start coding:

expo init social-authentication

cd social-authentication

expo install react-navigation react-navigation-stack react-native-gesture-handler react-native-reanimated react-native-screens expo-web-browser

npm install aws-amplify

We also need to initialize a new AWS Amplify project inside our app (accept the default values, you can customize them later).

amplify init

🛠 Create the navigation

Now we can start Expo and emulate our app with this command:

expo start

Once it has finished the initial loading, by pressing "i" key it will start up the Xcode emulator and it will also install the Expo app inside the emulated device.

Now you can open the project inside your favorite text editor.

Alt Text

In order to protect our app from unauthenticated use we are going to create the navigators using the previously installed react-navigation package, but before doing it we should create some screens:

/screens/HomeScreen.js

import React from 'react';
import {
    Button,
    View,
    Text
} from 'react-native';
import { Auth } from 'aws-amplify';

class HomeScreen extends React.Component {
    render(){
        return (
            <View>
                <Text> Home Screen </Text>
                <Button onPress={() => Auth.signOut()} title='Sign out'/>
            </View>
        )
    }
}

export default HomeScreen;

/screens/AuthScreen.js

import React from "react";
import {
  Button,
  View,
  StyleSheet
} from "react-native";
import { Auth } from 'aws-amplify';

class AuthScreen extends React.Component {

  render() {
    return (
        <View style={styles.authScreen} >
          <Button
            onPress={() => Auth.federatedSignIn({provider: 'Facebook'})}
            title="Authenticate with Facebook"
          />
        </View>
    );
  }

}

export default AuthScreen;

const styles = StyleSheet.create({
  authScreen: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  }
});

/screens/AuthLoadingScreen.js

import React from 'react';
import {
  ActivityIndicator,
  View,
} from 'react-native';
import { Auth, Hub } from 'aws-amplify';

class AuthLoadingScreen extends React.Component {

  async componentDidMount() {
    this._checkIfAuthenticated();
    Hub.listen('auth', async (data) => {
      switch (data.payload.event) {
        case 'signIn':
          this.props.navigation.navigate('Main');
          break;
        case 'signOut':
          this.props.navigation.navigate('Auth');
          break;
        default:
          break;
      }
    });
  }

  async _checkIfAuthenticated() {
    let currentSession = null;
    try {
      currentSession = await Auth.currentSession();
    } catch(err) {
      console.log(err);
    }
    this.props.navigation.navigate(currentSession ? 'Main' : 'Auth');
  };

  render() {
    return (
      <View>
        <ActivityIndicator size="large"/>
      </View>
    );
  }

}

export default AuthLoadingScreen;

After our component has been mounted we can use the Hub class from Amplify to create a "listener" that captures our auth events, so we can trigger an action when a User signs in or signs out.
In addition to this we can also check if there is a "currentSession" (through _checkIfAuthenticated function) in order to understand if the User has previously signed in in our app.

Now we can create the navigators:

  • AppNavigator: it is going to wrap all of our app navigation.

  • MainNavigator: it will be accessible only when we are correctly authenticated.

  • AuthNavigator: if we are unauthenticated we will be able to navigate only inside this navigator (AuthScreen).

/navigation/AppNavigator.js

import { createAppContainer, createSwitchNavigator } from 'react-navigation';

import AuthLoadingScreen from '../screens/AuthLoadingScreen';
import MainNavigator from './MainNavigator';
import AuthNavigator from './AuthNavigator';

export default createAppContainer(createSwitchNavigator(
    {
      AuthLoading: AuthLoadingScreen,
      Main: MainNavigator,
      Auth: AuthNavigator
    },
    {
      initialRouteName: 'AuthLoading',
    }
  )
);

/navigation/MainNavigator.js

import { createStackNavigator } from 'react-navigation-stack';

import HomeScreen from '../screens/HomeScreen';

export default createStackNavigator(
  {
    Home: { screen: HomeScreen }
  },
  { initialRouteName: 'Home' }
);

/navigation/AuthNavigator.js

import { createStackNavigator } from 'react-navigation-stack';

import AuthScreen from '../screens/AuthScreen';

export default createStackNavigator(
  {
    Auth: { screen: AuthScreen }
  }
);

Now we need to place the AppNavigator into our app entry point and this will be the component which wraps all the others.
In order to do this App.js has to look like that:

import React from 'react';
import AppNavigator from './navigation/AppNavigator';

class App extends React.Component {
  render() {
    return (
      <AppNavigator/>
    );
  }
}

export default App;

Now if you look at the emulator you will find yourself inside the AuthScreen (so inside AuthNavigator). Do not press the button yet, because we are now going to configure AWS Amplify resources to handle our authentication stack.

Alt Text

🛠 Create Auth resources with AWS Amplify

Open up the console inside the root of your App and enter this command:

amplify add auth

Enter the configuration used in the screenshot below:

Alt Text

When you need to insert Facebook AppID and AppSecret follow these instructions from AWS Amplify Docs.

Once you have successfully configured the Auth (that it's an AWS Cognito under the hood), you can:

amplify push

Confirm and wait until cloud resources creation is completed.

Congratulations 👏👏👏 You have successfully generated the Cognito Pool for your app, where users can sign up and be identified when they sign back in 🚀🔥

🔩 Configure AWS Amplify resources inside your app

Everything should be at his own place now and you will find a file called aws-exports.js inside your app root folder: open it and copy the value of the domain key and follow these steps.

We need to configure Amplify inside our App.js

import React from 'react';
import AppNavigator from './navigation/AppNavigator';

import Amplify from 'aws-amplify';
import awsconfig from './aws-exports';

Amplify.configure(awsconfig);

class App extends React.Component {
  render() {
    return (
      <AppNavigator/>
    );
  }
}

export default App;

The time to press the auth button in your app has come, if you complete the flow that appears inside the emulator screen you should be able to see the final result:

Alt Text

And that's all 🎉🎉🎉

This can be a starting point to begin the development of your application, if you want to extend your app with modern and serverless API be sure to give a read to AWS Amplify documentation.

You can also use my repo as a template to create your AWS Amplify project:

amplify init --app https://github.com/bastianbb/social-authentication

Top comments (7)

Collapse
 
maurock00 profile image
Mauricio Morales • Edited

Hi Bastian, I really enjoyed your post. Maybe you can help me. I'm having problems with the redirect urls, I can't get the app be redirect after login with facebook, It looks like any redirection is done after cognito save the user data. Please if you have a couple minutes to help me please let me know. Thanks

Collapse
 
bastianbavaresco profile image
Bastian Bavaresco

Hi Mauricio, thank you.
Have you added your success URL inside the Cognito Client configuration inside the AWS console?

Collapse
 
maurock00 profile image
Mauricio Morales • Edited

Thanks for answer my question Bastian, and sorry for the late reply, actually I'm having troubles to get a stable internet connection because of my current location. But yes, I'm using the expo URLs to get redirected but it seems like do nothing, because I expect to get the same authenticated page on your tuto but It is showing me the same page of login. I attached my config on Aws Console. Thanks again for your kind help.

Well, It does not allow me to attach the snapshot but the urls are the follwing:

Callback URL(s)
exp://127.0.0.1:19000/

Sign out URL(s)
exp://127.0.0.1:19000/

Regards.

Thread Thread
 
bastianbavaresco profile image
Bastian Bavaresco • Edited

Try by removing the "/" from the end of the endpoints.

Collapse
 
kris profile image
kris

This is a great guide to implement social authentication with React Native AWS amplify in the React Native app based on Expo eco-system. I love how the overall process is explained with code snippet and screenshots. It is easy to follow and grasp concept of AWS amplify in each step. Thanks for this.

Collapse
 
shantnu12345 profile image
Shantnu Kakkar • Edited

Thank you for compiling this. I am facing one issue. When I click login with facebook button, it redirects me to the browser correctly and asks for FB signin and password. However, after entering my credentials and pressing login in, It doesn't redirect me back to the app, instead it redirects to a infinite loading screen. Could anyone help me in resolving this? (Please note that user successfully gets added to AWS userpool after FB login, its just the redirect back to app that is not working).

I am using these redirects:
"redirectSignIn": "exp://127.0.0.1:19000",
"redirectSignOut": "exp://127.0.0.1:19000",
I have added these to my local aws_export.js and my console

Collapse
 
kris profile image
kris

The social authentications are an essential element of any app nowadays. You have made the integration of social authentications into React Native app simpler using the React Native AWS amplify. The article is simple and easy to follow. The stepwise guidance with coding implementation and screenshots are just great. It's really easy to learn from this. Kudos for this article.