FormidableLabs/react-native-app-auth

Name: react-native-app-auth

Owner: Formidable

Description: React native bridge for AppAuth - an SDK for communicating with OAuth2 providers

Created: 2017-11-13 17:59:31.0

Updated: 2018-01-17 15:19:18.0

Pushed: 2018-01-02 09:56:07.0

Homepage:

Size: 1266

Language: Objective-C

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

React Native App Auth

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

Build Status npm version

This is the API documentation for react-native-app-auth >= 2.0. See version 1.x documentation here.

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 and it has been tested with:

The library uses auto-discovery which means it relies on the the .well-known/openid-configuration endpoint to discover all auth endpoints automatically. It will be possible to extend the library later to add custom configuration.

Why you may want to use this library

AppAuth is a mature OAuth client implementation that follows the best practices set out in RFC 8252 - OAuth 2.0 for Native Apps including using SFAuthenticationSession and SFSafariViewController on iOS, and Custom Tabs on Android. WebViews are explicitly not supported due to the security and usability reasons explained in Section 8.12 of RFC 8252.

AppAuth also supports the PKCE (“Pixy”) extension to OAuth which was created to secure authorization codes in public clients when custom URI scheme redirects are used.

To learn more, read this short introduction to OAuth and PKCE on the Formidable blog.

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.

rt { authorize } from 'react-native-app-auth';

t config = {
suer: '<YOUR_ISSUER_URL>',
ientId: '<YOUR_CLIENT_ID>',
directUrl: '<YOUR_REDIRECT_URL>',
opes: '<YOUR_SCOPES_ARRAY>'


t result = await authorize(config);
config

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

result

This is the result from the auth server

refresh

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

rt { refresh } from 'react-native-app-auth';

t config = {
suer: '<YOUR_ISSUER_URL>',
ientId: '<YOUR_CLIENT_ID>',
directUrl: '<YOUR_REDIRECT_URL>',
opes: '<YOUR_SCOPES_ARRAY>',


t result = await refresh(config, {
freshToken: `<REFRESH_TOKEN>`

revoke

This method will revoke a token. The tokenToRevoke can be either an accessToken or a refreshToken

rt { revoke } from 'react-native-app-auth';

t config = {
suer: '<YOUR_ISSUER_URL>',
ientId: '<YOUR_CLIENT_ID>',
directUrl: '<YOUR_REDIRECT_URL>',
opes: '<YOUR_SCOPES_ARRAY>',


t result = await revoke(config, {
kenToRevoke: `<TOKEN_TO_REVOKE>`

Getting started
install react-native-app-auth --save
t-native link react-native-app-auth

Then follow the Setup steps to configure the native iOS and Android projects.

If you are not using react-native link, perform the Manual installation steps instead.

Manual installation
iOS
  1. In XCode, in the project navigator, right click Libraries ? Add Files to [your project's name]
  2. Go to node_modules ? react-native-app-auth and add RNAppAuth.xcodeproj
  3. In XCode, in the project navigator, select your project. Add libRNAppAuth.a to your project's Build Phases ? Link Binary With Libraries
  4. Run your project (Cmd+R)<
Android
  1. Open up android/app/src/main/java/[...]/MainActivity.java

  2. Add import com.reactlibrary.RNAppAuthPackage; to the imports at the top of the file

  3. Add new RNAppAuthPackage() to the list returned by the getPackages() method

  4. Append the following lines to android/settings.gradle:

    ude ':react-native-app-auth'
    ect(':react-native-app-auth').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-app-auth/android')
    
  5. Insert the following lines inside the dependencies block in android/app/build.gradle:

    pile project(':react-native-app-auth')
    
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.

CocoaPods

With CocoaPods, add the following line to your Podfile:

pod 'AppAuth', '>= 0.91'

Then run pod install. Note that version 0.91 is the first of the library to support iOS 11.

Carthage

With Carthage, add the following line to your Cartfile:

github "openid/AppAuth-iOS" "master"

Then run carthage bootstrap.

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:

>CFBundleURLTypes</key>
ay>
ict>
<key>CFBundleURLName</key>
<string>com.your.app.identifier</string>
<key>CFBundleURLSchemes</key>
<array>
  <string>io.identityserver.demo</string>
</array>
dict>
ray>
Define openURL callback in AppDelegate

You need to have a property in your AppDelegate to hold the auth session, in order to continue the authorization flow from the redirect. To add this, open AppDelegate.h in your project and add the following lines:

rotocol OIDAuthorizationFlowSession;

nterface AppDelegate : UIResponder <UIApplicationDelegate>
roperty(nonatomic, strong, nullable) id<OIDAuthorizationFlowSession> currentAuthorizationFlow;
roperty (nonatomic, strong) UIWindow *window;
nd

The authorization response URL is returned to the app via the iOS openURL app delegate method, so you need to pipe this through to the current authorization session (created in the previous instruction). To do this, open AppDelegate.m and add an import statement:

ort "AppAuth.h"

And in the bottom of the class, add the following handler:

OOL)application:(UIApplication *)app
        openURL:(NSURL *)url
        options:(NSDictionary<NSString *, id> *)options {
 ([_currentAuthorizationFlow resumeAuthorizationFlowWithURL:url]) {
_currentAuthorizationFlow = nil;
return YES;

turn NO;

Android Setup

To setup the Android project, you need to perform two steps:

  1. Install Android support libraries
  2. Add redirect scheme manifest placeholder
Install Android support libraries

This library depends on the AppAuth-Android project. The native dependencies for Android are automatically installed by Gradle, but you need to add the correct Android Support library version to your project:

  1. Add the Google Maven repository in your android/build.gradle
    sitories {
    gle()
    
    
  2. Make sure the appcompat version in android/app/build.gradle matches the one expected by AppAuth. If you generated your project using react-native init, you may have an older version of the appcompat libraries and need to upgdrade:
    ndencies {
    pile "com.android.support:appcompat-v7:25.3.1"
    
    
  3. If necessary, update the compileSdkVersion to 25:
    oid {
    pileSdkVersion 25
    
    
Add redirect scheme manifest placeholder

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

oid {
faultConfig {
manifestPlaceholders = [
  appAuthRedirectScheme: 'io.identityserver.demo'
]


The scheme is the beginning of your OAuth Redirect URL, up to the scheme separator (:) character.

Usage
rt { authorize } from 'react-native-app-auth';

ase config
t config = {
suer: '<YOUR_ISSUER_URL>',
ientId: '<YOUR_CLIENT_ID>',
directUrl: '<YOUR_REDIRECT_URL>',
opes: '<YOUR_SCOPES_ARRAY>'


se the client to make the auth request and receive the authState
{
nst result = await authorize(config);
 result includes accessToken, accessTokenExpirationDate and refreshToken
tch (error) {
nsole.log(error);

See example configurations for different providers below.

Identity Server 4

This library supports authenticating for Identity Server 4 out of the box. Some quirks:

  1. In order to enable refresh tokens, offline_access must be passed in as a scope variable
  2. In order to revoke the access token, we must sent client id in the method body of the request. This is not part of the OAuth spec.
ote "offline_access" scope is required to get a refresh token
t config = {
suer: 'https://demo.identityserver.io',
ientId: 'native.code',
directUrl: 'io.identityserver.demo:/oauthredirect',
opes: ['openid', 'profile', 'offline_access']


og in to get an authentication token
t authState = await authorize(config);

efresh token
t refreshedState = await refresh({
.config,
freshToken: authState.refreshToken,


evoke token, note that Identity Server expects a client id on revoke
t revoke(config, {
kenToRevoke: refreshedState.refreshToken,
ndClientId: true

Google

Full support out of the box.

t config = {
suer: 'https://accounts.google.com',
ientId: 'GOOGLE_OAUTH_APP_GUID.apps.googleusercontent.com',
directUrl: 'com.googleusercontent.apps.GOOGLE_OAUTH_APP_GUID:/oauth2redirect/google',
opes: ['openid', 'profile', 'offline_access']


og in to get an authentication token
t authState = await authorize(config);

efresh token
t refreshedState = await refresh(config, {
freshToken: authState.refreshToken


evoke token
t revoke(config, {
kenToRevoke: refreshedState.refreshToken

Okta

Full support out of the box.

If you're using Okta and want to add App Auth to your React Native application, you'll need an application to authorize against. If you don't have an Okta Developer account, you can signup for free.

Log in to your Okta Developer account and navigate to Applications > Add Application. Click Native and click the Next button. Give the app a name you?ll remember (e.g., React Native), select Refresh Token as a grant type, in addition to the default Authorization Code. Copy the Login redirect URI (e.g., com.oktapreview.dev-158606:/callback) and save it somewhere. You'll need this value when configuring your app.

Click Done and you'll see a client ID on the next screen. Copy the redirect URI and clientId values into your App Auth config.

t config = {
suer: 'https://{yourOktaDomain}.com/oauth2/default',
ientId: '{clientId}',
directUrl: 'com.{yourReversedOktaDomain}:/callback',
opes: ['openid', 'profile']


og in to get an authentication token
t authState = await authorize(config);

efresh token
t refreshedState = await refresh(config, {
freshToken: authState.refreshToken,


evoke token
t revoke(config, {
kenToRevoke: refreshedState.refreshToken

Keycloak

Keycloak does not specify a revocation endpoint so revoke functionality doesn't work.

If you use JHipster's default Keycloak Docker image, everything will work with the following settings, except for revoke.

t config = {
suer: 'http://localhost:9080/auth/realms/jhipster',
ientId: 'web_app',
directUrl: '<YOUR_REDIRECT_SCHEME>:/callback'
opes: ['openid', 'profile']


og in to get an authentication token
t authState = await authorize(config);

efresh token
t refreshedState = await refresh(config, {
freshToken: authState.refreshToken,

Contributors

Thanks goes to these wonderful people (emoji key):

|
Kadi Kraman

? ? ? ?? ? ? |
Jani Eväkallio

? ? ?? ? ? |
Phil Plückthun

? ? ? |
Imran Sulemanji

? ? |
JP

? ? |
Matt Cubitt

? ? | | :—: | :—: | :—: | :—: | :—: | :—: |

This project follows the all-contributors specification. Contributions of any kind are welcome!


This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.