Social Authentication - React-Native with a NodeJS Server
Tags: reactnative, authentication, react, javascript
Published: 2021-06-05 15:06:54

> I particularly write this post, just because I got lost or can't find any resources to teach me how to do this thing the right way!

![cover image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9qd2tds8oq1nsn67gq5x.png)

##### Hey there! 😃 

This is a special scenario where your react native application is running with your own NodeJS server where you have social authentication that should be done through a browser popup and getting back to the app.

This post assumes that you already have these setup:
* react-native app
* nodejs server hosted
* social authentication integrated to the server

### The Goal 💡

The mobile app should be able to login via a intermediate browser and the AUTH token is sent back to the app. This should work for both IOS and Android.

Let's have an overview how the flow looks like

`MOBILE_APP` -> `BROWSER` -> `GOOGLE AUTH WEBSITE` -> `TOKEN` -> `RETURN BACK TO APP` -> `TOKEN USED`

### Getting Started 🚀

First let's install the intermediate browser thing, after a long search a perfect match was found to get the job done.

Install the npm module to your react-native app
`npm install react-native-inappbrowser-reborn --save`

This module does the job much greater than expected! 

**For IOS**
`cd ios && pod install && cd`

**For Android**
```java
buildscript {
  ext {
    buildToolsVersion = "28.0.3"
    minSdkVersion = 16
    compileSdkVersion = 28
    targetSdkVersion = 28
    # Only using Android Support libraries
    supportLibVersion = "28.0.0" 
  }
```

### Let's get the job done ✅

Say my nodejs social authentication end point is

`https://sample.herokuapp.com/api/google/auth`

Make sure your endpoint gives you a response back in this format:

**For IOS**
`your_app_name://Home?token=your_auth_token`

**For Android**
`your_app_name://my-host/Home?token=your_auth_token`

##### Your React Native App

###### Import Statements
```js
import { InAppBrowser } from 'react-native-inappbrowser-reborn';
import { Alert, Platform } from 'react-native';
```
###### Create a Deep Link Function that helps us to get back to the app
```js
const getDeepLink = (path = '') => {
    const scheme = 'your_app_name';
    const prefix =
      Platform.OS === 'android' ? `${scheme}://my-host/` : `${scheme}://`;
    return prefix + path;
};
```
###### Inside the login function
```js
const handleLogIn = () => {
     const url = 'https://sample.herokuapp.com/api/google/auth';
     const redirectedURL = getDeepLink('Home');
     if (InAppBrowser.isAvailable()) {
        try {
          InAppBrowser.openAuth(url, redirectedURL)
                      .then((result) => {
                         return handleAuthNow(result);
                      })
                      .catch((e) => {
                         console.log(e);
                      });
        } catch (error) {
          Alert.alert(error);
        }
     } else {
       Alert.alert("Sorry Not Compatible!");
     }
};
```
###### handleAuthNow() function
```js
const handleAuthNow = (result) => {
const token = result?.url?.split('?token=')[1]?.slice(0, -1);
// console.log(token)
// use the token whatever you need to do
// most probably we would store the token into the asyncStorage of the app
// do not forget to close the browser
InAppBrowser.close();
};
```
#### Do not forget to do these before you test it

**For IOS**
- add the below to the `Info.plist` present inside the ios directory
- do not forget to replace the your_name_app with your own app name
```swift
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleTypeRole</key>
    <string>Editor</string>
    <key>CFBundleURLName</key>
    <string>your_name_app</string>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>your_name_app</string>
    </array>
  </dict>
</array>
```

**For Android**
- Inside your app `AndroidManifest.xml` file add these
- these code should be inside the
```java
<activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
        android:launchMode="singleTask"
        android:windowSoftInputMode="adjustResize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
// ADDED HERE
<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="your_app_name" android:host="my-host" android:pathPrefix="" />
</intent-filter>
// ADDED HERE
      </activity>
```

### What could go wrong and chances of getting lost 🤯
- As the token is passed through a browser with the url could end up having a extra hash at the end of the url that is sent back to the app, make sure you got an eye on it.
- As there is been a window opened between the app while returning back to the app, it could have not loaded again some code that should be running in order to have the token in the header of the request.
- Make sure you have specific url that is returned back to app for android and ios.


You could use the browser module in two ways:
* could be used for the authentication purpose.
* could be used to open URLs within your app.

###### To open the url inside your app
`InAppBrowser.open('https://google.com/')`

Here the browser could be customized to your own styles by including the options after the url. Refer: [Link](https://www.npmjs.com/package/react-native-inappbrowser-reborn)

## When to use this method 🤔

Only when,
- your react-native app is dependent on a third party server like nodejs hosted separately, as if you don't have a separate server you could simply use a oauth sdk for mobile development.

DISCLAIMER ❌
The above method was used and tested for both android and ios and the implementation method was based on my requirement you could refer the official browser module as they have another kind of method that makes the app to receive the token wherever you need in the app and not only in the login screen.

Hope not everyone would get lost just like me! 😃
Have a nice day!