React-native authentication with Google OAuth 2

abnaceur
5 min readAug 1, 2020

--

As a mobile developer at certain phase you will have to implement an OAuth 2 strategy using social media or other means.

This article won’t explain what is Oauth 2, or how does it work as there are an abundance of articles online about this matter.

The question is should I use Oauth 2 on client or on the server side ?

Client side

There are several packages like :

react-native-oauth, see repository here.

react-native-simple-auth see repository here.

I tried some of this packages where there are cons and pros

Pros :

  • It is an open source packages.
  • There are many implementation examples.
  • Easy to be implemented (Not all packages).

Cons :

  • Package maintenance.
  • Extra configuration for redirect URI.
  • No client control.
  • Can not access the return data from OAuth 2 callback directly by the server.

Server side

Implementing server side is more secure and manageable.

Let start our demonstration :

For the client we will use react-native and for the server side we will use NodeJs/ExpressJs.

1 — Create a new react-native application :

npx react-native init AwesomeProject

Note : — Follow the official documentation for Android/Ios environment setup here.

2 — Create server project :

npx express-generator server

For more information about ExpressJs go here.

3 — In the server side let’s install passport packages

npm i -save passport-google-oauth20 passport

Now what’s next, we will need to configure API call / callback for the OAuth 2 in Google developer console

a — Navigate and login to : https://console.developers.google.com/

b — Create a new project

c — Once created, select project oauth2demo and go to credentials

d — Click on “Create credentials” and choose “Oauth client ID”

e — Configure the consent screen, choose external, and follow the instructions to create the Oauth2 client ID.

f — Setup authorized JavaScript origins : as we are using a mobile application locally we don’t have access directly to localhost so in this case we will use pagekite to expose our server externally add : http://42music.pagekite.me (Here add your own URL)

For more information about pagekite here.

g — Setup authorized redirect URIs : add : http://42music.pagekite.me/auth/google/callback (Here add your own URL)

Save and get your ClientId and secret which we will use in the server with passport strategy.

Now let configure the server : -

In app.js initialize passpor within express app

var passport = require('passport');
// Initialize passprt
app.use(passport.initialize());

- Setup the passport strategy in /route/index.js

- Add passport serializeUser and deserializeUser

-Create the routes for the callback

var express = require('express');
var router = express.Router();
var passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;passport.serializeUser((user, done) => {
done(null, user);
})
passport.deserializeUser((user, done) => {
done(null, user)
})
/* GET home page. */router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
passport.use(new GoogleStrategy({
clientID: "", // Add your clientID
clientSecret: "", // Add the secret here
callbackURL: '/auth/google/callback'
}, (accessToken, refreshToken, profile, done) => {
done(null, profile, accessToken );
}))
// Googe Oauth2router.get('/auth/google', passport.authenticate('google', {
scope: ['profile', 'email'],
}));
// Google Oauth2 callback urlrouter.get('/auth/google/callback', passport.authenticate('google'), (req, res, next) => {
res.redirect("msrm42app://msrm42app.io?id=" + req.user.id);
});
module.exports = router;

Demo

Let’s setup our React-native application :

a — Start your react-native app on virtual or physical device

b — in App.js create a button for google OAuth 2 with a link to : http://42music.pagekite.me/auth/google

import React, { useEffect, useState } from 'react';
import {
SafeAreaView,
StyleSheet,
ScrollView,
TouchableOpacity,
Linking,
View,
Text,
StatusBar,
} from 'react-native';

import {
Header,
Colors,
} from 'react-native/Libraries/NewAppScreen';

const App: () => React$Node = () => {
const [data, setData] = useState("");

const handleOpenURL = ({ url }) => {
if (url.indexOf("?id") !== -1) {
if (url)
setData(url);
}
};

useEffect(() => {
// Your code here
Linking.addEventListener('url', handleOpenURL);
}, []);

return (
<>
<StatusBar barStyle="dark-content" />
<SafeAreaView>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={styles.scrollView}>
<Header />
<Text>
{data === "" ? null : data}
</Text>
<View style={styles.body}>
<TouchableOpacity style={styles.socialBtn}
onPress={() => Linking.openURL('http://42music.pagekite.me/auth/google')}>
<Text style={styles.buttonText} >
{data === "" ? "Connect via Google" : "You are connected !"}</Text>
</TouchableOpacity>
</View>
</ScrollView>
</SafeAreaView>
</>
);
};

const styles = StyleSheet.create({
body: {
backgroundColor: Colors.white,
},
socialBtn: {
margin: 30,
backgroundColor: '#1f5c9e',
paddingVertical: 10,
},
buttonText: {
color: '#fff',
fontWeight: 'bold',
textAlign: 'center'
},
});

export default App;

c — Once the OAuth2 google is successful we need to redirect the user to our application, and for so we will use react-native deep linking.

In ./android/app/src/main/AndroidManifest.xml add an intent-filter

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.oauth2app">
<uses-permission android:name="android.permission.INTERNET" /><application
android:name=".MainApplication"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:allowBackup="false"
android:theme="@style/AppTheme">
<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>
<intent-filter android:label="musicroom">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="msrm42app" android:host="msrm42app.io" />
</intent-filter>


</activity>

<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>
</manifest>

d — in the server side once the Oauth2 is successful redirect to the application :

res.redirect("msrm42app://msrm42app.io?id=" + req.user.id);

Input password and then connect

You can use the same method to implement other strategies.

Source code here.

--

--

abnaceur
abnaceur

Responses (4)