|
| 1 | +# OAuth2Client |
| 2 | + |
| 3 | +An OAuth2 library for Mac OS X & iOS (Cocoa & Cocoa touch). |
| 4 | + |
| 5 | +## Description |
| 6 | + |
| 7 | +This library is based on [draft 10 of the OAuth2 spec](http://tools.ietf.org/html/draft-ietf-oauth-v2-10). |
| 8 | +It implements the [native application profile](http://tools.ietf.org/html/draft-ietf-oauth-v2-10#section-1.4.3) |
| 9 | +and supports the end-user authorization endpoint via an internal or an external user-agent. Furthermore it |
| 10 | +also supports the user credentials flow by prompting the end-user for their username and password and use them |
| 11 | +directly to obtain an access token. See the description of the delegate for more information how to choose the |
| 12 | +authentication flow. |
| 13 | + |
| 14 | +## Getting started |
| 15 | + |
| 16 | +### Get the sources |
| 17 | + |
| 18 | +Getting the sources is as easy as doing a: |
| 19 | +`git clone git://github.com/nxtbgthng/OAuth2Client.git` |
| 20 | + |
| 21 | +### Manually including the library in your Xcode project |
| 22 | + |
| 23 | +#### iOS projects |
| 24 | + |
| 25 | +* Place the _OAuth2Client_ folder within your source root |
| 26 | +* Drag the _OAuth2Client.xcodeproj_ into your project |
| 27 | +* Under your build target, select the _Build Phases_ tab. |
| 28 | + * Under _Target Dependencies_ add _OAuth2Client_ |
| 29 | + * Under _Link Binary With Libraries_, add _libOAuth2Client.a_ |
| 30 | +* Under _Build Settings_, |
| 31 | + * Add `$(SRCROOT)/path/to/OAuth2Client` _Header Search Paths_, set as _recursive_ |
| 32 | + * Add `-ObjC` to _Other Linker Flags_ |
| 33 | +* `#import "NXOAuth2.h"` |
| 34 | +* add the Security.framework as a build dependency |
| 35 | + |
| 36 | +#### Desktop Mac projects |
| 37 | + |
| 38 | +- drag the OAuth2Client.xcodeproj into your project |
| 39 | +- add OAuth2Client.framework as a build dependency |
| 40 | +- add the Security.framework as a build dependency |
| 41 | +- add `$(CONFIGURATION_BUILD_DIR)/$(CONTENTS_FOLDER_PATH)/Frameworks` to your targets Framework Search Path |
| 42 | +- link your target against OAuth2Client (drag the OAuth2Client.framework product from OAuth2Client.xcodeproj |
| 43 | +to your targets *Link Binary With Libraries*) |
| 44 | +- `#import <OAuth2Client/NXOAuth2.h>` |
| 45 | + |
| 46 | +*Using the library as a framework in desktop applications is fairly untested. Please |
| 47 | +[report any issues](http://github.com/nxtbgthng/OAuth2Client/issues) and help in making the library better.* |
| 48 | + |
| 49 | +### Adding the libary to your project using CocoaPods |
| 50 | +[CocoaPods](http://cocoapods.org/) is a dependency manager for Xcode projects. It manages the above |
| 51 | +installation steps automatically. |
| 52 | + |
| 53 | +In order to install the library this way add the following line to your `Podfile`: |
| 54 | + |
| 55 | +```pod 'NXOAuth2Client', '~> 1.2.2'``` |
| 56 | + |
| 57 | +and run the following command `pod install`. |
| 58 | + |
| 59 | +## Using the OAuth2Client |
| 60 | + |
| 61 | +### Configure your Client |
| 62 | + |
| 63 | +The best place to configure your client is `+[UIApplicationDelegate initialize]` on iOS or `+[NSApplicationDelegate initialize]` on Mac OS X. There you can call `-[NXOAuth2AccountStore setClientID:secret:authorizationURL:tokenURL:redirectURL:forAccountType:]` on the shared account store for each service you want to have access to from your application. The account type is a string which is used as an identifier for a certain service. |
| 64 | + |
| 65 | +<pre> |
| 66 | ++ (void)initialize; |
| 67 | +{ |
| 68 | + [[NXOAuth2AccountStore sharedStore] setClientID:@"xXxXxXxXxXxX" |
| 69 | + secret:@"xXxXxXxXxXxX" |
| 70 | + authorizationURL:[NSURL URLWithString:@"https://...your auth URL..."] |
| 71 | + tokenURL:[NSURL URLWithString:@"https://...your token URL..."] |
| 72 | + redirectURL:[NSURL URLWithString:@"https://...your redirect URL..."] |
| 73 | + forAccountType:@"myFancyService"]; |
| 74 | +} |
| 75 | +</pre> |
| 76 | + |
| 77 | +### Requesting Access to a Service |
| 78 | + |
| 79 | +Once you have configured your client you are ready to request access to one of those services. The NXOAuth2AccountStore provides three different methods for this: |
| 80 | + |
| 81 | +- Username and Password |
| 82 | + <pre> |
| 83 | + [[NXOAuth2AccountStore sharedStore] requestAccessToAccountWithType:@"myFancyService" |
| 84 | + username:aUserName |
| 85 | + password:aPassword]; |
| 86 | + </pre> |
| 87 | + |
| 88 | +- External Browser |
| 89 | + <pre> |
| 90 | + [[NXOAuth2AccountStore sharedStore] requestAccessToAccountWithType:@"myFancyService"]; |
| 91 | + </pre> |
| 92 | + |
| 93 | + If you are using an external browser, your application needs to handle the URL you have registered as an redirect URL for the account type. The service will redirect to that URL after the authentication process. |
| 94 | + |
| 95 | +- Provide an Authorization URL Handler |
| 96 | + <pre> |
| 97 | + [[NXOAuth2AccountStore sharedStore] requestAccessToAccountWithType:@"myFancyService" |
| 98 | + withPreparedAuthorizationURLHandler:^(NSURL *preparedURL){ |
| 99 | + // Open a web view or similar |
| 100 | + }]; |
| 101 | + </pre> |
| 102 | + Using an authorization URL handler gives you the ability to open the URL in an own web view or do some fancy stuff for authentication. Therefor you pass a block to the NXOAuth2AccountStore while requesting access. |
| 103 | + |
| 104 | +#### On Success |
| 105 | + |
| 106 | +After a successful authentication, a new `NXOAuth2Account` object is in the list of accounts of `NXOAuth2AccountStore`. You will receive a notification of type `NXOAuth2AccountStoreAccountsDidChangeNotification`, e.g., for updating your UI. |
| 107 | +<pre> |
| 108 | +[[NSNotificationCenter defaultCenter] addObserverForName:NXOAuth2AccountStoreAccountsDidChangeNotification |
| 109 | + object:[NXOAuth2AccountStore sharedStore] |
| 110 | + queue:nil |
| 111 | + usingBlock:^(NSNotification *aNotification){ |
| 112 | + // Update your UI |
| 113 | + }]; |
| 114 | +</pre> |
| 115 | +If an account was added the `userInfo` dictionary of the notification will contain the new account at the `NXOAuth2AccountStoreNewAccountUserInfoKey`. Note though that this notification can be triggered on other events (e.g. account removal). In that case this key will not be set. |
| 116 | + |
| 117 | +#### On Failure |
| 118 | + |
| 119 | +If the authentication did not succeed, a notification of type `NXOAuth2AccountStoreDidFailToRequestAccessNotification` containing an `NSError` will be send. |
| 120 | +<pre> |
| 121 | +[[NSNotificationCenter defaultCenter] addObserverForName:NXOAuth2AccountStoreDidFailToRequestAccessNotification |
| 122 | + object:[NXOAuth2AccountStore sharedStore] |
| 123 | + queue:nil |
| 124 | + usingBlock:^(NSNotification *aNotification){ |
| 125 | + NSError *error = [aNotification.userInfo objectForKey:NXOAuth2AccountStoreErrorKey]; |
| 126 | + // Do something with the error |
| 127 | + }]; |
| 128 | +</pre> |
| 129 | + |
| 130 | +### Getting a List of all Accounts |
| 131 | + |
| 132 | +The authenticated accounts can be accessed via the `NXOAuth2AccountStore`. Either the complete list, only a list of accounts for a specific service or an account with an identifier (maybe cached in the user settings). |
| 133 | + |
| 134 | +<pre> |
| 135 | +for (NXOAuth2Account *account in [[NXOAuth2AccountStore sharedStore] accounts]) { |
| 136 | + // Do something with the account |
| 137 | +}; |
| 138 | + |
| 139 | +for (NXOAuth2Account *account in [[NXOAuth2AccountStore sharedStore] accountsWithAccountType:@"myFancyService"]) { |
| 140 | + // Do something with the account |
| 141 | +}; |
| 142 | + |
| 143 | +NXOAuth2Account *account = [[NXOAuth2AccountStore sharedStore] accountWithIdentifier:@"...cached account id..."]; |
| 144 | +</pre> |
| 145 | + |
| 146 | +Each `NXOAuth2Account` has a property `userData` which can be used to store some related information for that account. |
| 147 | +<pre> |
| 148 | +NXOAuth2Account *account = // ... get an account |
| 149 | +NSDictionary *userData = // ... |
| 150 | + |
| 151 | +account.userData = userData; |
| 152 | +</pre> |
| 153 | + |
| 154 | +This payload will be stored together with the accounts in the Keychain. Thus it shouldn't be to big. |
| 155 | + |
| 156 | +### Invoking a Request |
| 157 | + |
| 158 | +An request using the authentication for a service can be invoked via `NXOAuth2Request`. The most convenient method (see below) is a class method which you pass the method, a resource and some parameters (or nil) for the request and to handlers (both optional). One for a progress and the other for the response. The account is used for authentication and can be nil. Then a normal request without authentication will be invoked. |
| 159 | +<pre> |
| 160 | +[NXOAuth2Request performMethod:@"GET" |
| 161 | + onResource:[NSURL URLWithString:@"https://...your service URL..."] |
| 162 | + usingParameters:nil |
| 163 | + withAccount:anAccount |
| 164 | + sendProgressHandler:^(unsigned long long bytesSend, unsigned long long bytesTotal) { // e.g., update a progress indicator } |
| 165 | + responseHandler:^(NSURLResponse *response, NSData *responseData, NSError *error){ |
| 166 | + // Process the response |
| 167 | + }]; |
| 168 | +</pre> |
| 169 | + |
| 170 | +#### Getting a signed NSURLRequest |
| 171 | + |
| 172 | +In some circumstances you have to go the *god old way* and use an `NSURLConnection`. Maybe if you to download a large file. Therefor `NXOAuth2Request` gives you the possibility to get an `NSURLRequest` containing the additional information to authenticate that request. |
| 173 | + |
| 174 | +<pre> |
| 175 | +NXOAuth2Request *theRequest = [[NXOAuth2Request alloc] initWithResource:[NSURL URLWithString:@"https://...your service URL..."] |
| 176 | + method:@"GET" |
| 177 | + parameters:nil]; |
| 178 | +theRequest.account = // ... an account |
| 179 | + |
| 180 | +NSURLRequest *sigendRequest = [theRequest signedURLRequest]; |
| 181 | + |
| 182 | +[theRequest release]; |
| 183 | + |
| 184 | +// Invoke the request with you preferd method |
| 185 | +</pre> |
| 186 | + |
| 187 | +## BSD License |
| 188 | + |
| 189 | +Copyright © 2012, nxtbgthng GmbH |
| 190 | + |
| 191 | +All rights reserved. |
| 192 | + |
| 193 | +Redistribution and use in source and binary forms, with or without |
| 194 | +modification, are permitted provided that the following conditions are met: |
| 195 | + |
| 196 | +* Redistributions of source code must retain the above copyright |
| 197 | + notice, this list of conditions and the following disclaimer. |
| 198 | +* Redistributions in binary form must reproduce the above copyright |
| 199 | + notice, this list of conditions and the following disclaimer in the |
| 200 | + documentation and/or other materials provided with the distribution. |
| 201 | +* Neither the name of nxtbgthng nor the |
| 202 | + names of its contributors may be used to endorse or promote products |
| 203 | + derived from this software without specific prior written permission. |
| 204 | + |
| 205 | +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| 206 | +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 207 | +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 208 | +DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY |
| 209 | +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 210 | +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 211 | +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 212 | +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 213 | +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 214 | +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
0 commit comments