|
| 1 | +--- |
| 2 | +sidebar_position: 1 |
| 3 | +slug: / |
| 4 | +--- |
| 5 | + |
| 6 | +# Introduction |
| 7 | + |
| 8 | +Get started by installing the dependencies in your application |
| 9 | + |
| 10 | +```sh |
| 11 | +yarn add react-native-app-auth |
| 12 | +``` |
| 13 | +Or |
| 14 | +```sh |
| 15 | +npm install react-native-app-auth --save |
| 16 | +``` |
| 17 | + |
| 18 | +## Usage |
| 19 | + |
| 20 | +```javascript |
| 21 | +import { authorize } from 'react-native-app-auth'; |
| 22 | + |
| 23 | +// base config |
| 24 | +const config = { |
| 25 | + issuer: '<YOUR_ISSUER_URL>', |
| 26 | + clientId: '<YOUR_CLIENT_ID>', |
| 27 | + redirectUrl: '<YOUR_REDIRECT_URL>', |
| 28 | + scopes: ['<YOUR_SCOPE_ARRAY>'], |
| 29 | +}; |
| 30 | + |
| 31 | +// use the client to make the auth request and receive the authState |
| 32 | +try { |
| 33 | + const result = await authorize(config); |
| 34 | + // result includes accessToken, accessTokenExpirationDate and refreshToken |
| 35 | +} catch (error) { |
| 36 | + console.log(error); |
| 37 | +} |
| 38 | +``` |
| 39 | + |
| 40 | +## Setup |
| 41 | + |
| 42 | +### iOS Setup |
| 43 | + |
| 44 | +To setup the iOS project, you need to perform three steps: |
| 45 | + |
| 46 | +1. [Install native dependencies](#install-native-dependencies) |
| 47 | +2. [Register redirect URL scheme](#register-redirect-url-scheme) |
| 48 | +3. [Define openURL callback in AppDelegate](#define-openurl-callback-in-appdelegate) |
| 49 | + |
| 50 | +#### Install native dependencies |
| 51 | + |
| 52 | +This library depends on the native [AppAuth-ios](https://github.com/openid/AppAuth-iOS) project. To |
| 53 | +keep the React Native library agnostic of your dependency management method, the native libraries |
| 54 | +are not distributed as part of the bridge. |
| 55 | + |
| 56 | +AppAuth supports three options for dependency management. |
| 57 | + |
| 58 | +1. **CocoaPods** |
| 59 | + |
| 60 | + ```sh |
| 61 | + cd ios |
| 62 | + pod install |
| 63 | + ``` |
| 64 | + |
| 65 | +2. **Carthage** |
| 66 | + |
| 67 | + With [Carthage](https://github.com/Carthage/Carthage), add the following line to your `Cartfile`: |
| 68 | + |
| 69 | + github "openid/AppAuth-iOS" "master" |
| 70 | + |
| 71 | + Then run `carthage update --platform iOS`. |
| 72 | + |
| 73 | + Drag and drop `AppAuth.framework` from `ios/Carthage/Build/iOS` under `Frameworks` in `Xcode`. |
| 74 | + |
| 75 | + 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. |
| 76 | + |
| 77 | +3. **Static Library** |
| 78 | + |
| 79 | + You can also use [AppAuth-iOS](https://github.com/openid/AppAuth-iOS) as a static library. This |
| 80 | + requires linking the library and your project and including the headers. Suggested configuration: |
| 81 | + |
| 82 | + 1. Create an XCode Workspace. |
| 83 | + 2. Add `AppAuth.xcodeproj` to your Workspace. |
| 84 | + 3. Include libAppAuth as a linked library for your target (in the "General -> Linked Framework and |
| 85 | + Libraries" section of your target). |
| 86 | + 4. Add `AppAuth-iOS/Source` to your search paths of your target ("Build Settings -> "Header Search |
| 87 | + Paths"). |
| 88 | +
|
| 89 | +#### Register redirect URL scheme |
| 90 | +
|
| 91 | +If you intend to support iOS 10 and older, you need to define the supported redirect URL schemes in |
| 92 | +your `Info.plist` as follows: |
| 93 | +
|
| 94 | +```xml |
| 95 | +<key>CFBundleURLTypes</key> |
| 96 | +<array> |
| 97 | + <dict> |
| 98 | + <key>CFBundleURLName</key> |
| 99 | + <string>com.your.app.identifier</string> |
| 100 | + <key>CFBundleURLSchemes</key> |
| 101 | + <array> |
| 102 | + <string>io.identityserver.demo</string> |
| 103 | + </array> |
| 104 | + </dict> |
| 105 | +</array> |
| 106 | +``` |
| 107 | +
|
| 108 | +- `CFBundleURLName` is any globally unique string. A common practice is to use your app identifier. |
| 109 | +- `CFBundleURLSchemes` is an array of URL schemes your app needs to handle. The scheme is the |
| 110 | + beginning of your OAuth Redirect URL, up to the scheme separator (`:`) character. E.g. if your redirect uri |
| 111 | + is `com.myapp://oauth`, then the url scheme will is `com.myapp`. |
| 112 | +
|
| 113 | +#### Define openURL callback in AppDelegate |
| 114 | +
|
| 115 | +You need to retain the auth session, in order to continue the |
| 116 | +authorization flow from the redirect. Follow these steps: |
| 117 | +
|
| 118 | +`RNAppAuth` will call on the given app's delegate via `[UIApplication sharedApplication].delegate`. |
| 119 | +Furthermore, `RNAppAuth` expects the delegate instance to conform to the protocol `RNAppAuthAuthorizationFlowManager`. |
| 120 | +Make `AppDelegate` conform to `RNAppAuthAuthorizationFlowManager` with the following changes to `AppDelegate.h`: |
| 121 | +
|
| 122 | +##### For react-native >= 0.68 |
| 123 | +
|
| 124 | +```diff |
| 125 | ++ #import <React/RCTLinkingManager.h> |
| 126 | ++ #import "RNAppAuthAuthorizationFlowManager.h" |
| 127 | +
|
| 128 | +- @interface AppDelegate : RCTAppDelegate |
| 129 | ++ @interface AppDelegate : RCTAppDelegate <RNAppAuthAuthorizationFlowManager> |
| 130 | +
|
| 131 | ++ @property(nonatomic, weak) id<RNAppAuthAuthorizationFlowManagerDelegate> authorizationFlowManagerDelegate; |
| 132 | +``` |
| 133 | +
|
| 134 | +Add the following code to `AppDelegate.mm` to support React Navigation deep linking and overriding browser behavior in the authorization process |
| 135 | +
|
| 136 | +```diff |
| 137 | ++ - (BOOL) application: (UIApplication *)application |
| 138 | ++ openURL: (NSURL *)url |
| 139 | ++ options: (NSDictionary<UIApplicationOpenURLOptionsKey, id> *) options |
| 140 | ++ { |
| 141 | ++ if ([self.authorizationFlowManagerDelegate resumeExternalUserAgentFlowWithURL:url]) { |
| 142 | ++ return YES; |
| 143 | ++ } |
| 144 | ++ return [RCTLinkingManager application:application openURL:url options:options]; |
| 145 | ++ } |
| 146 | +``` |
| 147 | +
|
| 148 | +If you want to support universal links, add the following to `AppDelegate.mm` under `continueUserActivity` |
| 149 | +
|
| 150 | +```diff |
| 151 | ++ - (BOOL) application: (UIApplication *) application |
| 152 | ++ continueUserActivity: (nonnull NSUserActivity *)userActivity |
| 153 | ++ restorationHandler: (nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler |
| 154 | ++ { |
| 155 | ++ if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) { |
| 156 | ++ if (self.authorizationFlowManagerDelegate) { |
| 157 | ++ BOOL resumableAuth = [self.authorizationFlowManagerDelegate resumeExternalUserAgentFlowWithURL:userActivity.webpageURL]; |
| 158 | ++ if (resumableAuth) { |
| 159 | ++ return YES; |
| 160 | ++ } |
| 161 | ++ } |
| 162 | ++ } |
| 163 | ++ return [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler]; |
| 164 | ++ } |
| 165 | +``` |
| 166 | +
|
| 167 | +##### For react-native < 0.68 |
| 168 | +
|
| 169 | +```diff |
| 170 | ++ #import "RNAppAuthAuthorizationFlowManager.h" |
| 171 | +
|
| 172 | +- @interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate> |
| 173 | ++ @interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, RNAppAuthAuthorizationFlowManager> |
| 174 | +
|
| 175 | ++ @property(nonatomic, weak)id<RNAppAuthAuthorizationFlowManagerDelegate>authorizationFlowManagerDelegate; |
| 176 | +``` |
| 177 | +
|
| 178 | +Add the following code to `AppDelegate.m` (to support iOS 10, React Navigation deep linking and overriding browser behavior in the authorization process) |
| 179 | +
|
| 180 | +```diff |
| 181 | ++ - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *, id> *) options { |
| 182 | ++ if ([self.authorizationFlowManagerDelegate resumeExternalUserAgentFlowWithURL:url]) { |
| 183 | ++ return YES; |
| 184 | ++ } |
| 185 | ++ return [RCTLinkingManager application:app openURL:url options:options]; |
| 186 | ++ } |
| 187 | +``` |
| 188 | +
|
| 189 | +If you want to support universal links, add the following to `AppDelegate.m` under `continueUserActivity` |
| 190 | +
|
| 191 | +```diff |
| 192 | ++ if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) { |
| 193 | ++ if (self.authorizationFlowManagerDelegate) { |
| 194 | ++ BOOL resumableAuth = [self.authorizationFlowManagerDelegate resumeExternalUserAgentFlowWithURL:userActivity.webpageURL]; |
| 195 | ++ if (resumableAuth) { |
| 196 | ++ return YES; |
| 197 | ++ } |
| 198 | ++ } |
| 199 | ++ } |
| 200 | +``` |
| 201 | +
|
| 202 | +#### Integration of the library with a Swift iOS project |
| 203 | +
|
| 204 | +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. |
| 205 | +
|
| 206 | +Steps: |
| 207 | +
|
| 208 | +1. `swift-Bridging-Header.h` should include a reference to `#import "RNAppAuthAuthorizationFlowManager.h`, like so: |
| 209 | +
|
| 210 | +```h |
| 211 | +#import <React/RCTBundleURLProvider.h> |
| 212 | +#import <React/RCTRootView.h> |
| 213 | +#import <React/RCTBridgeDelegate.h> |
| 214 | +#import <React/RCTBridge.h> |
| 215 | +#import "RNAppAuthAuthorizationFlowManager.h" // <-- Add this header |
| 216 | +#if DEBUG |
| 217 | +#import <FlipperKit/FlipperClient.h> |
| 218 | +// etc... |
| 219 | +``` |
| 220 | +
|
| 221 | +2. `AppDelegate.swift` should implement the `RNAppAuthorizationFlowManager` protocol and have a handler for url deep linking. The result should look something like this: |
| 222 | +
|
| 223 | +```swift |
| 224 | +@UIApplicationMain |
| 225 | +class AppDelegate: UIApplicationDelegate, RNAppAuthAuthorizationFlowManager { //<-- note the additional RNAppAuthAuthorizationFlowManager protocol |
| 226 | + public weak var authorizationFlowManagerDelegate: RNAppAuthAuthorizationFlowManagerDelegate? // <-- this property is required by the protocol |
| 227 | + //"open url" delegate function for managing deep linking needs to call the resumeExternalUserAgentFlowWithURL method |
| 228 | + func application( |
| 229 | + _ app: UIApplication, |
| 230 | + open url: URL, |
| 231 | + options: [UIApplicationOpenURLOptionsKey: Any] = [:]) -> Bool { |
| 232 | + return authorizationFlowManagerDelegate?.resumeExternalUserAgentFlow(with: url) ?? false |
| 233 | + } |
| 234 | +} |
| 235 | +``` |
| 236 | +
|
| 237 | +### Android Setup |
| 238 | +
|
| 239 | +**Note:** for RN >= 0.57, you will get a warning about compile being obsolete. To get rid of this warning, use [patch-package](https://github.com/ds300/patch-package) to replace compile with implementation [as in this PR](https://github.com/FormidableLabs/react-native-app-auth/pull/242) - we're not deploying this right now, because it would break the build for RN < 57. |
| 240 | +
|
| 241 | +To setup the Android project, you need to add redirect scheme manifest placeholder: |
| 242 | +
|
| 243 | +To [capture the authorization redirect](https://github.com/openid/AppAuth-android#capturing-the-authorization-redirect), |
| 244 | +add the following property to the defaultConfig in `android/app/build.gradle`: |
| 245 | +
|
| 246 | +``` |
| 247 | +android { |
| 248 | + defaultConfig { |
| 249 | + manifestPlaceholders = [ |
| 250 | + appAuthRedirectScheme: 'io.identityserver.demo' |
| 251 | + ] |
| 252 | + } |
| 253 | +} |
| 254 | +``` |
| 255 | +
|
| 256 | +The scheme is the beginning of your OAuth Redirect URL, up to the scheme separator (`:`) character. E.g. if your redirect uri |
| 257 | +is `com.myapp://oauth`, then the url scheme will is `com.myapp`. The scheme must be in lowercase. |
| 258 | +
|
| 259 | +NOTE: When integrating with [React Navigation deep linking](https://reactnavigation.org/docs/deep-linking/#set-up-with-bare-react-native-projects), 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](https://github.com/FormidableLabs/react-native-app-auth/issues/494#issuecomment-797394994). |
0 commit comments