react-native-identyum-auth
TypeScript icon, indicating that this package has built-in type declarations

0.1.1 • Public • Published

logo

React Native App Auth

React native bridge for Identyum AppAuth - an SDK for communicating with Identyum OAuth2

npm package version Maintenance Status

This versions supports react-native@0.63+.

React Native bridge for AppAuth-iOS and AppAuth-Android SDKS for communicating with OAuth 2.0 and OpenID Connect providers.

This library should support any OAuth provider that implements the OAuth2 spec.

We only support the Authorization Code Flow.

Supported methods

See Usage for example configurations, and the included Example application for a working sample.

authorize

This is the main function to use for authentication. Invoking this function will do the whole login flow and returns the access token, refresh token and access token expiry date when successful, or it throws an error when not successful.

import { authorize } from 'react-native-identyum-auth';

const config = {
  clientId: '<YOUR_CLIENT_ID>',
  redirectUrl: '<YOUR_REDIRECT_URL>',
  scopes: ['<YOUR_SCOPES_ARRAY>'],
  env: '<ENVIRONMENT>'
};

const result = await authorize(config);

prefetchConfiguration

ANDROID This will prefetch the authorization service configuration. Invoking this function is optional and will speed up calls to authorize. This is only supported on Android.

import { prefetchConfiguration } from 'react-native-identyum-auth';

const config = {
  clientId: '<YOUR_CLIENT_ID>',
  redirectUrl: '<YOUR_REDIRECT_URL>',
  scopes: ['<YOUR_SCOPES_ARRAY>'],
  env: '<ENVIRONMENT>'
};

prefetchConfiguration(config);

config

This is your configuration object for the client. The config is passed into each of the methods with optional overrides.

  • clientId - (string) REQUIRED your client id on the auth server
  • redirectUrl - (string) REQUIRED the url that links back to your app with the auth code
  • scopes - (array<string>) the scopes for your token, e.g. [ 'liveness_check' 'id_video_check' 'id_scan'].
  • env - (string) name of desired environment. Can be either SAND for sandbox environment or PROD for production environment.

result

This is the result from the auth server:

  • accessToken - (string) the access token
  • accessTokenExpirationDate - (string) the token expiration date
  • tokenAdditionalParameters - (Object) additional url parameters from the tokenEndpoint response.
  • refreshToken - (string) the refresh token
  • tokenType - (string) the token type, e.g. Bearer
  • scopes - ([string]) the scopes the user has agreed to be granted

refresh

This method will refresh the accessToken using the refreshToken. Some auth providers will also give you a new refreshToken

import { refresh } from 'react-native-identyum-auth';

const config = {
  clientId: '<YOUR_CLIENT_ID>',
  redirectUrl: '<YOUR_REDIRECT_URL>',
  scopes: ['<YOUR_SCOPES_ARRAY>'],
  env: '<ENVIRONMENT>'

};

const result = await refresh(config, {
  refreshToken: `<REFRESH_TOKEN>`,
});

Getting started

npm install react-native-identyum-auth --save

Setup

iOS Setup

To setup the iOS project, you need to perform three steps:

  1. Install native dependencies
  2. Register redirect URL scheme
  3. Define openURL callback in AppDelegate
Install native dependencies

This library depends on the native AppAuth-ios project. To keep the React Native library agnostic of your dependency management method, the native libraries are not distributed as part of the bridge.

AppAuth supports three options for dependency management.

  1. CocoaPods

    cd ios
    pod install
  2. Carthage

    With Carthage, add the following line to your Cartfile:

     github "openid/AppAuth-iOS" "master"
    

    Then run carthage update --platform iOS.

    Drag and drop AppAuth.framework from ios/Carthage/Build/iOS under Frameworks in Xcode.

    Add a copy files build step for AppAuth.framework: open Build Phases on Xcode, add a new "Copy Files" phase, choose "Frameworks" as destination, add AppAuth.framework and ensure "Code Sign on Copy" is checked.

  3. Static Library

    You can also use AppAuth-iOS as a static library. This requires linking the library and your project and including the headers. Suggested configuration:

    1. Create an XCode Workspace.
    2. Add AppAuth.xcodeproj to your Workspace.
    3. Include libAppAuth as a linked library for your target (in the "General -> Linked Framework and Libraries" section of your target).
    4. Add AppAuth-iOS/Source to your search paths of your target ("Build Settings -> "Header Search Paths").
Register redirect URL scheme

If you intend to support iOS 10 and older, you need to define the supported redirect URL schemes in your Info.plist as follows:

<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLName</key>
    <string>com.your.app.identifier</string>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>io.identityserver.demo</string>
    </array>
  </dict>
</array>
  • CFBundleURLName is any globally unique string. A common practice is to use your app identifier.
  • CFBundleURLSchemes is an array of URL schemes your app needs to handle. The scheme is the beginning of your OAuth Redirect URL, up to the scheme separator (:) character. E.g. if your redirect uri is com.myapp://oauth, then the url scheme will is com.myapp.
Define openURL callback in AppDelegate

You need to retain the auth session, in order to continue the authorization flow from the redirect. Follow these steps:

RNAppAuth will call on the given app's delegate via [UIApplication sharedApplication].delegate. Furthermore, RNAppAuth expects the delegate instance to conform to the protocol RNAppAuthAuthorizationFlowManager. Make AppDelegate conform to RNAppAuthAuthorizationFlowManager with the following changes to AppDelegate.h:

+ #import "RNAppAuthAuthorizationFlowManager.h"

- @interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate>
+ @interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, RNAppAuthAuthorizationFlowManager>

+ @property(nonatomic, weak)id<RNAppAuthAuthorizationFlowManagerDelegate>authorizationFlowManagerDelegate;

Add the following code to AppDelegate.m (to support iOS <= 10 and React Navigation deep linking)

+ - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *, id> *) options {
+  if ([self.authorizationFlowManagerDelegate resumeExternalUserAgentFlowWithURL:url]) {
+    return YES;
+  }
+  return [RCTLinkingManager application:app openURL:url options:options];
+ }

If you want to support universal links, add the following to AppDelegate.m under continueUserActivity

+ if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
+   if (self.authorizationFlowManagerDelegate) {
+     BOOL resumableAuth = [self.authorizationFlowManagerDelegate resumeExternalUserAgentFlowWithURL:userActivity.webpageURL];
+     if (resumableAuth) {
+       return YES;
+     }
+   }
+ }

Integration of the library with a Swift iOS project

The approach mentioned should work with Swift. In this case one should make AppDelegate conform to RNAppAuthAuthorizationFlowManager. Note that this is not tested/guaranteed by the maintainers.

Steps:

  1. swift-Bridging-Header.h should include a reference to #import "RNAppAuthAuthorizationFlowManager.h, like so:
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTBridgeDelegate.h>
#import <React/RCTBridge.h>
#import "RNAppAuthAuthorizationFlowManager.h" // <-- Add this header
#if DEBUG
#import <FlipperKit/FlipperClient.h>
// etc...
  1. AppDelegate.swift should implement the RNAppAuthorizationFlowManager protocol and have a handler for url deep linking. The result should look something like this:
@UIApplicationMain
class AppDelegate: UIApplicationDelegate, RNAppAuthAuthorizationFlowManager { //<-- note the additional RNAppAuthAuthorizationFlowManager protocol
  public weak var authorizationFlowManagerDelegate: RNAppAuthAuthorizationFlowManagerDelegate? // <-- this property is required by the protocol
  //"open url" delegate function for managing deep linking needs to call the resumeExternalUserAgentFlowWithURL method
  func application(
      _ app: UIApplication,
      open url: URL,
      options: [UIApplicationOpenURLOptionsKey: Any] = [:]) -> Bool {
      return authorizationFlowManagerDelegate?.resumeExternalUserAgentFlowWithURL(with: url) ?? false
  }
}

Android Setup

Note: for RN >= 0.57, you will get a warning about compile being obsolete. To get rid of this warning, use patch-package to replace compile with implementation as in this PR - we're not deploying this right now, because it would break the build for RN < 57.

To setup the Android project, you need to add redirect scheme manifest placeholder:

To capture the authorization redirect, add the following property to the defaultConfig in android/app/build.gradle:

android {
  defaultConfig {
    manifestPlaceholders = [
      appAuthRedirectScheme: 'io.identityserver.demo'
    ]
  }
}

The scheme is the beginning of your OAuth Redirect URL, up to the scheme separator (:) character. E.g. if your redirect uri is com.myapp://oauth, then the url scheme will is com.myapp.

NOTE: When integrating with React Navigation deep linking, be sure to make this scheme (and the scheme in the config's redirectUrl) unique from the scheme defined in the deep linking intent-filter. E.g. if the scheme in your intent-filter is set to com.myapp, then update the above scheme/redirectUrl to be com.myapp.auth as seen here.

Usage

import { authorize } from 'react-native-identyum-auth';

// base config
const config = {
  clientId: '<YOUR_CLIENT_ID>',
  redirectUrl: '<YOUR_REDIRECT_URL>',
  scopes: ['<YOUR_SCOPE_ARRAY>'],
  env: '<ENVIRONMENT>',
};

// use the client to make the auth request and receive the authState
try {
  const result = await authorize(config);
  // result includes accessToken, accessTokenExpirationDate and refreshToken
} catch (error) {
  console.log(error);
}

Error messages

Values are in the code field of the rejected Error object.

  • OAuth Authorization error codes
  • OAuth Access Token error codes
  • service_configuration_fetch_error - could not fetch the service configuration
  • authentication_failed - user authentication failed
  • token_refresh_failed - could not exchange the refresh token for a new JWT
  • browser_not_found (Android only) - no suitable browser installed

Token Storage

Recommendations on secure token storage can be found here.

Maintenance Status

Active: Identyum is actively working on this project, and we expect to continue for work for the foreseeable future. Bug reports, feature requests and pull requests are welcome.

Package Sidebar

Install

npm i react-native-identyum-auth

Weekly Downloads

0

Version

0.1.1

License

MIT

Unpacked Size

122 kB

Total Files

22

Last publish

Collaborators

  • zpopovcic-identyum