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!
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
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
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
const getDeepLink = (path = '') => {
const scheme = 'your_app_name';
const prefix =
Platform.OS === 'android' ? `${scheme}://my-host/` : `${scheme}://`;
return prefix + path;
};
Inside the login function
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
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
<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
<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
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!
Top comments (1)
isn't better to use auth0.com or eartho.io?