OAuth 2 with React Native keeping Expo

Roberto Vázquez González
ITNEXT
Published in
4 min readOct 16, 2018

--

I’m a frictionless guy, developer mainly because I enjoy the process of creation of new applications and I like to use them and enjoy with the process, trying to avoid as much as I can the time I spend on manual deployments configuration process. Basically, I Prefer to spend this time doing than resolving config problems.

React Native (RN) is a game-changing technology in the mobile development world, a lot of magic is happening in the background in order to transform the React code to native code transparently.

But using RN without Expo makes you have to deal with Xcode, Android Studio to generate the packages and deploy your application to the Play and App Store, and this means to have to deal with more configuration dependent to 2 completely different platforms cocoapods and swift for iOS and gradle and Java for Android.

That’s why the existence of Expo makes sense.

Why Expo is so needed when working with RN

I have to say the default output from create-react-native-app produces a React Native + Expo project, so we don't have to do anything special to have Expo up and running.

The reasons why for me setting the project up with expo makes sense are described in the following points:

  • Resolve the testing scaffolding.
  • Allow you to execute and play with the application on real devices without having to set up your devices as development devices
  • Generate .ipa (iOS App Store Package) and .apk (Android PacKage) to deploying to App Stores through their server without having to deal with XCode (which makes mandatory to have a Mac computer) and JDK.
  • Sugar additions like tunnel deployment (allowing devices out of your Network to try your application during development ).
  • A tool to open the emulators through the CLI or the browser with just one click.
  • And offering their own SDK to deal with specific device possibilities in a transparent way.

And the best thing as I said before, the configuration comes resolved out of the box with create-react-native-app

Our First Authentication Solution

At Precursive, when we started to use Apex Rest API within our React Native application we also needed to resolve the authentication from a different way than any other application we made inside the Salesforce development.

I try to give a try to follow the official documentation, and in the case of Salesforce was using the Salesforce Mobile SDK with forcereact create as is described in their trailhead

This react-native-force module provides 4 packages with useful Salesforce utilities 'import {oauth, network, smartstore, smartsync} from 'react-native-force'; and we can use oauth.authenticate to Login to Salesforce, but this project is not using expo.

In summary; Good and frictionless solution but because it generates the project with react-native-force and it doesn't use expo. It generates dependent iOS and Android code with the forceios and forceandroid native modules.

Other O Auth2 with RN

Salesforce provides Authenticate Apps with OAuth so OAuth looks like the standard to use for authentication.

So I checked the different RN libraries out there to resolve this O Auth.

  • OAuth login for React Native. This one provides easy setup for this social networks (Google, Facebook, Twitter and Tumblr).
  • react-native-oauth provides an interface to OAuth 1.0 and OAuth 2.0 providers with support for the following providers for React Native apps (Twitter, Facebook, Google, Github, and Slack)
  • React Native App Auth React native bridge for AppAuth — an SDK for communicating with OAuth2 providers, this is the one which looks more standard, in my opinion,.

But all of them uses native modules and Expo doesn’t currently support them, meaning we need to eject the application to install those libraries, and this means no expo in the project 😢.

Our solution to don’t leave Expo

So before accepting the fact that OAuth libraries are not compatible with Expo, I checked the Expo SDK and I found something which we could use to resolve our problems AuthSession.

This package is already included in Expo, so basically, we just need to use it to make the login.

So here a quick simple SignInScreen component showing how to log in to Salesforce using Expo Auth-session (of course we also need to have connected application set up correctly following SF instructions).

import React, { Component } from 'react';
import { SF_OAUTH_URL, REMOTE_ACCESS_CONSUMER_KEY } from 'react-native-dotenv';
import { AsyncStorage, Button, View, Text } from 'react-native';
import { AuthSession } from 'expo';
import { globalStyles } from '../constants/Styles';
import ScreenKeys from '../constants/ScreenKeys';
export default class SignInScreen extends Component {
static navigationOptions = {
title: 'Please sign in',
};
state = {
errorCode: null,
};
_signInAsync = async () => {
const { navigation } = this.props;
const redirectUrl = AuthSession.getRedirectUrl();
const result = await AuthSession.startAsync({
authUrl:
`${SF_OAUTH_URL}` +
`?response_type=token` +
`&client_id=${REMOTE_ACCESS_CONSUMER_KEY}` +
`&prompt=login` +
`&redirect_uri=${encodeURIComponent(redirectUrl)}`,
});
console.log(result);
const { type, errorCode = 'You cancel or dismissed the login' } = result;
if (type === 'success') {
// Just simple way to store the token in this examples
await AsyncStorage.setItem('userToken', JSON.stringify(result));
navigation.navigate(ScreenKeys.main);
} else {
/**
* Result types can be: cancel, dismissed or error (with errorCode)
*/
this.setState({ errorCode });
}
};
render() {
const { errorCode } = this.state;
return (
<View style={globalStyles.container}>
<Button title="Sign in!" onPress={this._signInAsync} />
{errorCode ? <Text>{errorCode}</Text> : null}
</View>
);
}
}

With this steps, we can login to Salesforce orgs through RN application and then use Apex Rest API and work with Salesforce servers as any other standard Rest server, making our development work as standard and frictionless as possibles keeping Expo 🚀.

Originally published at robertovg.com.

--

--

JS Engineer with 10+ years experience, CorkerSpace.com Co-founder and 🏄🧘‍🎸 - Currently focused on the frontend, UX, and FP. 💛js (^es6) - robertovg.com -