DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • How to Build Scalable Mobile Apps With React Native: A Step-by-Step Guide
  • Cross-Platform Mobile Application Development: Evaluating Flutter, React Native, HTML5, Xamarin, and Other Frameworks
  • Common Problems in Redux With React Native
  • How To Integrate the Stripe Payment Gateway Into a React Native Application

Trending

  • Using Python Libraries in Java
  • Can You Run a MariaDB Cluster on a $150 Kubernetes Lab? I Gave It a Shot
  • Building a Real-Time Audio Transcription System With OpenAI’s Realtime API
  • AI Speaks for the World... But Whose Humanity Does It Learn From?
  1. DZone
  2. Coding
  3. JavaScript
  4. Add a Login Feature to a React Native Application

Add a Login Feature to a React Native Application

By 
Matt Raible user avatar
Matt Raible
·
Jan. 13, 20 · Tutorial
Likes (2)
Comment
Save
Tweet
Share
22.9K Views

Join the DZone community and get the full member experience.

Join For Free

React Native is an open-source mobile application framework for developing native Android and iOS apps. React components translate to native platform components, as opposed to using JavaScript/HTML and a web view. making React Native is ready to use in your current iOS and Android apps. 

In this tutorial, I’ll show you how to use React Native with Okta to implement a login feature in an app within ten minutes. For authorization, we’ll use OAuth 2.0, and for authentication, we’ll use OpenID Connect. Authentication allows us to verify who the user is, and authorization gives the user access to what they’re allowed to do. Okta makes authentication implementation super easy and even more so with React Native and Okta’s React Native SDK.

React Native 0.61 was just released a couple of weeks ago. One of its biggest features is Fast Refresh — a unification of live reloading (reload on save) and hot reloading. Fast Refreshfully supports modern React’s functional components and hooks and recovers after typos and other mistakes. In previous versions of React Native, a common complaint was that “hot reloading” was broken.

Prerequisites:

  • Node 10.
  • Yarn.
  • Watchman.
  • Java 8 (for Android).
  • An Okta Developer Account.

To install these prerequisites on a Mac, Linux, or Windows Subsystem for Linux (WSL), I recommend using Homebrew.

Plain Text
 




x


 
1
brew install node
2
brew install yarn
3
brew install watchman
4
brew tap AdoptOpenJDK/openjdk
5
brew cask install adoptopenjdk8



If you’re not using WSL for Windows, you can use Chocolatey to install everything from the command line:

Shell
 




xxxxxxxxxx
1


 
1
choco install -y nodejs.install python2 jdk8



You’ll also need to download and install IDEs for Android and iOS:

  • Android Studio (for Android).
  • Xcode (for iOS).

If you’d rather watch a video, I created a screencast of this tutorial.

Create a React Native Application

The React Native CLI is a popular way to get started with React Native development.

Shell
 




xxxxxxxxxx
1


 
1
npm install -g react-native-cli@2.0.1



Once you have React Native CLI installed, you can create a new application using the init command.

Shell
 




xxxxxxxxxx
1


 
1
react-native init ReactNativeLogin



Add Login With OIDC

Okta provides a React Native SDK which conveniently wraps the Okta native Android OIDC and iOS OIDC libraries.

I’m going to show you two ways to add OIDC-based login with Okta: The fast way with a tool I created and the step-by-step instructions.

This tool is based on Schematics and manipulates your project to install and configure everything.

Install Schematics globally.

Shell
 




xxxxxxxxxx
1


 
1
npm install -g @angular-devkit/schematics-cli@0.803.7



Create a Native App in Okta

Log in to your Okta Developer account (or sign up if you don’t have an account).

  • From the Applications page, choose Add Application.
  • On the Create New Application page, select Native as the platform, and click Next.
  • Give your app a memorable name, select Refresh Token as a grant type, and click Done.
  • Click the Edit button and add a Logout redirect URI that matches the default Login redirect URI (e.g., com.okta.dev-123456:/callback).
  • Click Save.

Install React Native OIDC Login

In a terminal, navigate into your ReactNativeLogin directory and install OktaDev Schematics:

Shell
 




xxxxxxxxxx
1


 
1
npm i @oktadev/schematics@1.0.0



Note: If you have a React Native 0.60.x app, use @oktadev/schematics@0.9.0. The only difference between the two is the tests.

Run the add-auth schematic in your ReactNativeLogin project.

Shell
 




xxxxxxxxxx
1


 
1
schematics @oktadev/schematics:add-auth



You will be prompted for an issuer and a clientId. You can find your issuer under API > Authorization Servers on Okta.


The client ID will be on your application screen.


This process will take a minute to complete.

Configure Your iOS Project to use Swift

React Native uses Objective-C, but the Okta React Native library uses Swift. Because of this, you have to add a Swift file in your iOS project for it to compile. Run the following command to open your native iOS project in Xcode.

Shell
 




xxxxxxxxxx
1


 
1
open ios/ReactNativeLogin.xcworkspace



To add a Swift file, complete the following steps:

  1. Right-click on your project and select New File….
  2. Select Swift File, and click Next.
  3. Enter a name (e.g., Polyfill) and click Create.
  4. If prompted for a header file, it is not required to create one.

Then, cd into ReactNativeLogin/ios and run pod install.

Tip: If you don’t have CocoaPoads installed, you can install it with gem install cocoapods.

Run Your React Native App on iOS

Navigate back to the root directory of your app. Start your app, and you should be able to authenticate with Okta. 

Plain Text
 




xxxxxxxxxx
1


 
1
react-native run-ios



Once you’re signed in, you’ll see options to log out, get the user’s information from an ID token, and get the user’s information from the React Native SDK’s  getUser() method (a.k.a. the request).



Note: The prompt when you click Login cannot be avoided. This is an iOS safety mechanism. It also pops up when you log out. See this issue for more information.

Run Your React Native App on Android

The schematic you ran modifies all the necessary files for Android; there are no code modifications required!

You will need to run an AVD (Android Virtual Device) before starting your app, or you can plug in your Android phone and use that. If you have neither, launch Android Studio and go to Tools > AVD Manager. Click Create Virtual Device at the bottom and select a phone of your choice. I chose a Pixel 3 XL with Android 10.

Start your AVD, then your app, and authenticate with Okta. 

Plain Text
 




xxxxxxxxxx
1


 
1
react-native run-android




Click the Get User from ID Token button to confirm you can retrieve the user’s information.

Run Installed React Native Authentication Tests

In addition to integrating login, OktaDev Schematics also installed some tests that verify login and authentication work. Run npm test to see these tests run in your terminal.

Plain Text
 




xxxxxxxxxx
1


 
1
Snapshot Summary
2
 › 1 snapshot written from 1 test suite.
3

          
4
Test Suites: 2 passed, 2 total
5
Tests:       12 passed, 12 total
6
Snapshots:   1 written, 1 total
7
Time:        8.952s
8
Ran all test suites.



Note: OktaDev Schematics puts tests in a tests directory rather than the default __tests__ directory because Angular Schematics uses double underscore as a placeholder.

Using a Custom Login Screen with Okta

This example showed you how to add an OIDC flow that opens a browser when a user logs in and logs out. If you require a smoother login experience that doesn’t pop open a browser, see Okta’s Custom Sign-In Example, for example, code that shows you how to implement that type of flow.

Add OIDC Login the Hard Way

The previous section showed you how to use OktaDev Schematics to quickly add a login feature (and tests!) to a React Native application. However, you might have an existing React Native application that doesn’t have the same structure as a brand new React Native application.

This section shows you everything that OktaDev Schematics does for you, in detail.

Create a project with React Native CLI and install Okta’s SDK.

Shell
 




xxxxxxxxxx
1


 
1
react-native init ReactNativeLogin
2
cd ReactNativeLogin
3
npm install @okta/okta-react-native@1.2.1



For iOS, modify ios/Podfile to change it from iOS 9 to iOS 11.

Shell
 




xxxxxxxxxx
1


 
1
platform :ios, '11.0'



Open your project in Xcode.

Shell
 




xxxxxxxxxx
1


 
1
open ios/ReactNativeLogin.xcworkspace



Add a Swift file.

  1. Right-click on your project and select New File….
  2. Select Swift File, and click Next.
  3. Enter a name (e.g., Polyfill) and click Create.
  4. If prompted for a header file, it is not required to create one.

Install iOS native dependencies with CocoaPods.

Shell
 




xxxxxxxxxx
1


 
1
cd ios
2
pod install


Add Jest and Enzyme to Test Your React Native Login

Jest is a library for testing JavaScript apps, and Enzyme is a library that makes it easier to select and query elements in tests. They’re often used alongside one another.

Install testing dependencies with npm.

Shell
 




xxxxxxxxxx
1


 
1
npm i enzyme@3.10.0 enzyme-adapter-react-16@1.14.0 enzyme-async-helpers@0.9.1 react-dom@16.9.0



Then, change your jest key in package.json to match the following:

JSON
 




xxxxxxxxxx
1
10


 
1
"jest": {
2
  "preset": "react-native",
3
  "automock": false,
4
  "transformIgnorePatterns": [
5
    "node_modules/(?!@okta|react-native)"
6
  ],
7
  "setupFiles": [
8
    "./setupJest.js"
9
  ]
10
}



Create setupJest.js to polyfill React Native for Okta.

JavaScript
 




xxxxxxxxxx
1
32


 
1
// Required to correctly polyfill React-Native
2

          
3
import { configure } from 'enzyme';
4
import Adapter from 'enzyme-adapter-react-16';
5
import { NativeModules } from 'react-native';
6

          
7
configure({ adapter: new Adapter() });
8

          
9
global.XMLHttpRequest = jest.fn();
10
global.fetch = jest.fn();
11

          
12
if (typeof window !== 'object') {
13
  global.window = global;
14
  global.window.navigator = {};
15
}
16

          
17
NativeModules.OktaSdkBridge = {
18
  createConfig: jest.fn(),
19
  signIn: jest.fn(),
20
  signOut: jest.fn(),
21
  getAccessToken: jest.fn(),
22
  getIdToken: jest.fn(),
23
  getUser: jest.fn(),
24
  isAuthenticated: jest.fn(),
25
  revokeAccessToken: jest.fn(),
26
  revokeIdToken: jest.fn(),
27
  revokeRefreshToken: jest.fn(),
28
  introspectAccessToken: jest.fn(),
29
  introspectIdToken: jest.fn(),
30
  introspectRefreshToken: jest.fn(),
31
  refreshTokens: jest.fn(),
32
};



Create Auth.js to handle your authentication code.

Java
 




xxxxxxxxxx
1
154


 
1
import React, { Component, Fragment } from 'react';
2

          
3
import { SafeAreaView, ScrollView, Button, StyleSheet, Text, View } from 'react-native';
4
import { createConfig, signIn, signOut, isAuthenticated, getUser, getUserFromIdToken, EventEmitter } from '@okta/okta-react-native';
5
import configFile from './auth.config';
6

          
7
export default class Auth extends Component {
8
  constructor() {
9
    super();
10
    this.state = {
11
      authenticated: false,
12
      context: null,
13
    };
14
    this.checkAuthentication = this.checkAuthentication.bind(this);
15
  }
16

          
17
  async componentDidMount() {
18
    let that = this;
19
    EventEmitter.addListener('signInSuccess', function (e: Event) {
20
      that.setState({authenticated: true});
21
      that.setContext('Logged in!');
22
    });
23
    EventEmitter.addListener('signOutSuccess', function (e: Event) {
24
      that.setState({authenticated: false});
25
      that.setContext('Logged out!');
26
    });
27
    EventEmitter.addListener('onError', function (e: Event) {
28
      console.warn(e);
29
      that.setContext(e.error_message);
30
    });
31
    EventEmitter.addListener('onCancelled', function (e: Event) {
32
      console.warn(e);
33
    });
34
    await createConfig({
35
      clientId: configFile.oidc.clientId,
36
      redirectUri: configFile.oidc.redirectUri,
37
      endSessionRedirectUri: configFile.oidc.endSessionRedirectUri,
38
      discoveryUri: configFile.oidc.discoveryUri,
39
      scopes: configFile.oidc.scopes,
40
      requireHardwareBackedKeyStore: configFile.oidc.requireHardwareBackedKeyStore,
41
    });
42
    this.checkAuthentication();
43
  }
44

          
45
  componentWillUnmount() {
46
    EventEmitter.removeAllListeners('signInSuccess');
47
    EventEmitter.removeAllListeners('signOutSuccess');
48
    EventEmitter.removeAllListeners('onError');
49
    EventEmitter.removeAllListeners('onCancelled');
50
  }
51

          
52
  async componentDidUpdate() {
53
    this.checkAuthentication();
54
  }
55

          
56
  async checkAuthentication() {
57
    const result = await isAuthenticated();
58
    if (result.authenticated !== this.state.authenticated) {
59
      this.setState({authenticated: result.authenticated});
60
    }
61
  }
62

          
63
  async login() {
64
    signIn();
65
  }
66

          
67
  async logout() {
68
    signOut();
69
  }
70

          
71
  async getUserIdToken() {
72
    let user = await getUserFromIdToken();
73
    this.setContext(JSON.stringify(user, null, 2));
74
  }
75

          
76
  async getMyUser() {
77
    let user = await getUser();
78
    this.setContext(JSON.stringify(user, null, 2));
79
  }
80

          
81
  setContext = message => {
82
    this.setState({
83
      context: message,
84
    });
85
  };
86

          
87
  renderButtons() {
88
    if (this.state.authenticated) {
89
      return (
90
        <View style={styles.buttonContainer}>
91
          <View style={styles.button}>
92
            <Button
93
              onPress={async () => {
94
                this.getUserIdToken();
95
              }}
96
              title="Get User From Id Token"
97
            />
98
          </View>
99
        </View>
100
      );
101
    }
102
  }
103

          
104
  render() {
105
    return (
106
      <Fragment>
107
        <SafeAreaView style={styles.container}>
108
          <View style={styles.buttonContainer}>
109
            <View style={styles.button}>
110
              {this.state.authenticated ? (
111
                <Button
112
                  style={styles.button}
113
                  testID="logoutButton"
114
                  onPress={async () => { this.logout() }}
115
                  title="Logout"
116
                />
117
              ) : (
118
                <Button
119
                  style={styles.button}
120
                  testID="loginButton"
121
                  onPress={async () => { this.login() }}
122
                  title="Login"
123
                />
124
              )}
125
            </View>
126
          </View>
127
          {this.renderButtons()}
128
          <ScrollView
129
            contentInsetAdjustmentBehavior="automatic"
130
            style={styles.context}>
131
            <Text>{this.state.context}</Text>
132
          </ScrollView>
133
        </SafeAreaView>
134
      </Fragment>
135
    );
136
  }
137
}
138

          
139
const styles = StyleSheet.create({
140
  buttonContainer: {
141
    flexDirection: 'column',
142
    justifyContent: 'space-between',
143
  },
144
  button: {
145
    width: 300,
146
    height: 40,
147
    marginTop: 10,
148
  },
149
  container: {
150
    flex: 1,
151
    flexDirection: 'column',
152
    alignItems: 'center',
153
  }
154
});



You might notice it imports a config file at the top.

JavaScript
 




xxxxxxxxxx
1


 
1
import configFile from './auth.config';



Create auth.config with your OIDC settings from Okta.

JSON
 




xxxxxxxxxx
1
10


 
1
export default {
2
  oidc: {
3
    clientId: '$yourClientId',
4
    redirectUri: 'com.okta.dev-#######:/callback',
5
    endSessionRedirectUri: 'com.okta.dev-#######:/callback',
6
    discoveryUri: 'https://dev-#######.okta.com/oauth2/default',
7
    scopes: ['openid', 'profile', 'offline_access'],
8
    requireHardwareBackedKeyStore: false,
9
  },
10
};



Create an app on Okta to get the values for $yourClientId and ######.

  • From the Applications page, choose Add Application.
  • On the Create New Application page, select Native as the platform, and click Next.
  • Give your app a memorable name, select Refresh Token as a grant type, and click Done.
  • Click the Edit button and add a Logout redirect URI that matches the default Login redirect URI (e.g., com.okta.dev-123456:/callback).
  • Click Save.

In App.js, import Auth.

JavaScript
 




xxxxxxxxxx
1


 
1
import Auth from './Auth';



Use it in a new <View /> after the Hermes logic.

Java
 




xxxxxxxxxx
1
19


 
1

          
2
<ScrollView
3
  contentInsetAdjustmentBehavior="automatic"
4
  style={styles.scrollView}>
5
  <Header />
6
  {global.HermesInternal == null ? null : (
7
    <View style={styles.engine}>
8
      <Text style={styles.footer}>Engine: Hermes</Text>
9
    </View>
10
  )}
11
  <View style={styles.body}>
12
    <View style={styles.sectionContainer}>
13
      <Text style={styles.sectionTitle}>Step Zero</Text>
14
      <Text style={styles.sectionDescription}>
15
        Use <Text style={styles.highlight}>Okta</Text> for
16
        authentication.
17
      </Text>
18
      <Auth />
19
    </View>



At this point, your tests will not pass because Okta uses an EventEmitter to communicate between components.

Add React Native Authentication Tests

To mock the native event emitter that Okta uses, add a mock for it in __tests__/App-test.js.

Java
 




xxxxxxxxxx
1
16


 
1
/**
2
 * @format
3
 */
4

          
5
import 'react-native';
6
import React from 'react';
7
import renderer from 'react-test-renderer';
8
import App from '../App';
9

          
10
jest.mock(
11
  '../node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter',
12
);
13

          
14
it('renders correctly', () => {
15
  renderer.create(<App />);
16
});



To make sure all the login and authentication logic works, create __tests__/Auth-test.js.

Java
 




xxxxxxxxxx
1
138


 
1
import React from 'react';
2
import Auth from '../Auth';
3
import { shallow } from 'enzyme';
4
import renderer from 'react-test-renderer';
5
import { waitForState } from 'enzyme-async-helpers';
6
import { NativeEventEmitter } from 'react-native';
7

          
8
const nativeEmitter = new NativeEventEmitter();
9

          
10
jest
11
  .mock(
12
    '../node_modules/react-native/Libraries/Components/StatusBar/StatusBar',
13
    () => 'StatusBar',
14
  )
15
  .mock(
16
    '../node_modules/react-native/Libraries/Components/ScrollView/ScrollView',
17
    () => 'ScrollView',
18
  )
19
  .mock(
20
    '../node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter',
21
  );
22

          
23
global.fetch = jest
24
  .fn()
25
  .mockImplementation(() => {
26
    return new Promise((resolve, reject) => {
27
      resolve({
28
        json: () => {
29
          return {
30
            user: [{ foo: 'foo', bar: 'bar' }],
31
          }
32
        },
33
        ok: true,
34
      });
35
    });
36
  })
37
  .mockImplementationOnce(() => {
38
    return new Promise((resolve, reject) => {
39
      resolve({
40
        json: () => {
41
          return {
42
            userinfo_endpoint: 'dummy_endpoint',
43
          }
44
        },
45
        ok: true,
46
      });
47
    });
48
  });
49

          
50
describe('auth setup', () => {
51
  it('should render without crashing', () => {
52
    const rendered = renderer.create(<Auth />).toJSON();
53
    expect(rendered).toBeTruthy();
54
  });
55

          
56
  it('should render correctly', () => {
57
    const rendered = renderer.create(<Auth />).toJSON();
58
    expect(rendered).toMatchSnapshot();
59
  });
60

          
61
  it('should initialize with default state', () => {
62
    const wrapper = shallow(<Auth />);
63
    expect(wrapper.state().authenticated).toBe(false);
64
    expect(wrapper.state().context).toBe(null);
65
  });
66

          
67
  it('should render login button if not authenticated', () => {
68
    const wrapper = shallow(<Auth />);
69
    const loginButton = wrapper.find('Button').get(0);
70
    expect(loginButton.props.title).toBe('Login');
71
  });
72

          
73
  it('should render logout and get user info buttons if authenticated', () => {
74
    const wrapper = shallow(<Auth />);
75
    wrapper.setState({authenticated: true});
76
    const logoutButton = wrapper.find('Button').get(0);
77
    const getUserFromIdButton = wrapper.find('Button').get(1);
78
    const getUserButton = wrapper.find('Button').get(2);
79
    expect(logoutButton.props.title).toBe('Logout');
80
    expect(getUserFromIdButton.props.title).toBe('Get User From Id Token');
81
    expect(getUserButton.props.title).toBe('Get User From Request');
82
  });
83

          
84
  it('should not render login button if authenticated', () => {
85
    const wrapper = shallow(<Auth />);
86
    wrapper.setState({authenticated: true});
87
    const loginButton = wrapper.find('Button').get(0);
88
    expect(loginButton.props.title).not.toBe('Login');
89
  });
90

          
91
  it('should not render logout and get user info buttons if not authenticated', () => {
92
    const wrapper = shallow(<Auth />);
93
    const logoutButton = wrapper.find('Button').get(0);
94
    const getUserFromIdButton = wrapper.find('Button').get(1);
95
    const getUserButton = wrapper.find('Button').get(2);
96
    expect(logoutButton.props.title).not.toBe('Logout');
97
    expect(getUserFromIdButton).toBe(undefined);
98
    expect(getUserButton).toBe(undefined);
99
  });
100
});
101

          
102
describe('authentication flow', () => {
103
  it('should detect when the user has logged in', async () => {
104
    const wrapper = shallow(<Auth />);
105
    const loginButton = wrapper.find('Button').get(0);
106
    await loginButton.props.onPress();
107
    expect(loginButton.props.title).toBe('Login');
108
    nativeEmitter.emit('signInSuccess');
109
    expect(wrapper.state().authenticated).toBe(true);
110
    expect(wrapper.state().context).toBe('Logged in!');
111
  });
112

          
113
  it('should detect when the user has signed out', async () => {
114
    const wrapper = shallow(<Auth />);
115
    wrapper.setState({authenticated: true});
116
    const logoutButton = wrapper.find('Button').get(0);
117
    await logoutButton.props.onPress();
118
    expect(logoutButton.props.title).toBe('Logout');
119
    nativeEmitter.emit('signOutSuccess');
120
    expect(wrapper.state().authenticated).toBe(false);
121
    expect(wrapper.state().context).toBe('Logged out!');
122
  });
123

          
124
  it('should return user profile information from id token' , async () => {
125
    const mockGetIdToken = require('react-native').NativeModules.OktaSdkBridge.getIdToken;
126
    mockGetIdToken.mockImplementationOnce(() => {
127
      // id_token returns { a: 'b' }
128
      return {'id_token': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8'};
129
    });
130
    const wrapper = shallow(<Auth />);
131
    wrapper.setState({authenticated: true});
132
    const profileButton = wrapper.find('Button').get(1);
133
    await profileButton.props.onPress();
134
    await waitForState(wrapper, state => state.context !== null);
135
    expect(profileButton.props.title).toBe('Get User From Id Token');
136
    expect(wrapper.state().context).toContain('"a": "b"');
137
  });
138
});



Run npm test to bask in the fruits of your labor!

To run your app on iOS, use react-native run-ios.


To run it on Android, you’ll need to modify your Gradle build files.

Okta’s React Native SDK depends on the Okta OIDC Android library. You have to add this library through Gradle.

  1. Add Okta’s BinTray repo to android/build.gradle, under allprojects -> repositories.
    Groovy
     




    xxxxxxxxxx
    1


     
    1
    maven {
    2
       url  "https://dl.bintray.com/okta/com.okta.android"
    3
    }


  2. Make sure your minSdkVersion is 19 in android/build.gradle.
  3. Define a redirect scheme to capture the authorization redirect. In android/app/build.gradle, under android -> defaultConfig, add:
     manifestPlaceholders = [ appAuthRedirectScheme: 'com.okta.dev-###### ]
    

Finally, start a virtual device (or plug in your phone), and run react-native run-android.

Learn More About React Native and OIDC Login

This tutorial showed you how to add a login feature to a React Native application. You learned that OAuth 2.0 is an authorization protocol, and OIDC is an authentication layer on top of it. You also used PKCE (Public Key Code Exchange) in your implementation, which is the more secure way to implement OAuth 2.0 in mobile applications.

I hope you enjoy your React Native development journey and its fast refresh feature!

You can find the source code for this example on GitHub at oktadeveloper/okta-react-native-login-example.

To learn more about React Native, OIDC, and PKCE, check out these posts:

  • Build an iOS App with React Native and Publish it to the App Store
  • Design and Develop an Android App with React Native and Publish to Google Play Store
  • Identity, Claims, & Tokens – An OpenID Connect Primer, Part 1 of 3
  • Implement the OAuth 2.0 Authorization Code with PKCE Flow
  • Why OAuth API Keys and Secrets Aren’t Safe in Mobile Apps

If you liked this tutorial, follow @oktadev on Twitter and subscribe to our YouTube channel.

Create a React Native App with Login in 10 Minutes was originally published on the Okta Developer Blog on November 14, 2019. 

React Native React (JavaScript library) mobile app authentication

Published at DZone with permission of Matt Raible, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • How to Build Scalable Mobile Apps With React Native: A Step-by-Step Guide
  • Cross-Platform Mobile Application Development: Evaluating Flutter, React Native, HTML5, Xamarin, and Other Frameworks
  • Common Problems in Redux With React Native
  • How To Integrate the Stripe Payment Gateway Into a React Native Application

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!