Skip to content

Commit bae6438

Browse files
committed
Merge branch 'develop'
2 parents cfef2ef + 36a2aa1 commit bae6438

File tree

9 files changed

+149
-9
lines changed

9 files changed

+149
-9
lines changed

Dist/OAuthiOS.framework/Versions/A/Headers/OAuthIOData.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
@property (nonatomic, strong) NSDictionary *request_conf;
3030

3131
@property (nonatomic, strong) NSString *oauth_token;
32+
@property (nonatomic, strong) NSString *code;
3233
@property (nonatomic, strong) NSString *oauth_token_secret;
3334
@property (nonatomic, strong) NSString *access_token;
3435
@property (nonatomic, strong) NSString *request_url;

Dist/OAuthiOS.framework/Versions/A/Headers/OAuthIOModal.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
@protocol OAuthIODelegate <NSObject>
2626
- (void)didReceiveOAuthIOResponse:(OAuthIORequest *)request;
2727
- (void)didFailWithOAuthIOError:(NSError *)error;
28+
- (void)didReceiveOAuthIOCode:(NSString *)code;
29+
- (void)didAuthenticateServerSide:(NSString *)body andResponse:(NSURLResponse *) response;
30+
- (void)didFailAuthenticationServerSide:(NSString *)body andResponse:(NSURLResponse *)response andError:(NSError *)error;
2831
@end
2932

3033
@interface OAuthIOModal : UIViewController<UIWebViewDelegate>
@@ -43,15 +46,19 @@
4346
UIWebView *_browser;
4447
UINavigationBar *_navigationBar;
4548
NSUInteger _navigationBarHeight;
49+
4650

4751
}
48-
52+
@property NSMutableArray *saved_cookies;
4953
@property (weak) id<OAuthIODelegate> delegate;
54+
@property NSURLSession *session;
55+
@property NSString *authUrl;
5056

5157
- (id)initWithKey:(NSString *)key delegate:(id)delegate;
5258
- (id)initWithKey:(NSString *)key delegate:(id)delegate andOptions:(NSDictionary *) options;
5359
- (void)showWithProvider:(NSString *)provider;
5460
- (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options;
61+
- (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options stateTokenUrl:(NSString*) stateUrl authUrl:(NSString*) authUrl;
5562
- (BOOL) clearCache;
5663
- (BOOL) clearCacheForProvider:(NSString *)provider;
5764
- (BOOL) cacheAvailableForProvider:(NSString *)provider;
139 KB
Binary file not shown.

OAuth.io.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
1616
#
1717

1818
s.name = "OAuth.io"
19-
s.version = "1.1.3"
19+
s.version = "1.2.0"
2020
s.summary = "OAuth that just works!"
2121

2222
s.description = <<-DESC
@@ -71,7 +71,7 @@ Pod::Spec.new do |s|
7171
# Supports git, hg, bzr, svn and HTTP.
7272
#
7373

74-
s.source = { :git => "https://github.com/oauth-io/oauth-ios.git", :tag => "1.1.3" }
74+
s.source = { :git => "https://github.com/oauth-io/oauth-ios.git", :tag => "1.2.0" }
7575

7676

7777
# ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #

OAuthiOS/Src/OAuthIOData.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
@property (nonatomic, strong) NSDictionary *request_conf;
3030

3131
@property (nonatomic, strong) NSString *oauth_token;
32+
@property (nonatomic, strong) NSString *code;
3233
@property (nonatomic, strong) NSString *oauth_token_secret;
3334
@property (nonatomic, strong) NSString *access_token;
3435
@property (nonatomic, strong) NSString *request_url;

OAuthiOS/Src/OAuthIOData.m

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ - (id)initWithDictionary:(NSDictionary *)dict
4040

4141
[_request setValue:_oauth_token forKey:@"oauth_token"];
4242
[_request setValue:_oauth_token_secret forKey:@"oauth_token_secret"];
43-
} else {
43+
} else if ([[dict objectForKey:@"data"] objectForKey:@"code"] != nil) {
44+
_code = [[dict objectForKey:@"data"] objectForKey:@"code"];
45+
_request = nil;
46+
}else {
4447
[NSException raise:@"Wrong credentials" format:@"A problem occured with the credentials data initialization"];
4548
}
4649

OAuthiOS/Src/OAuthIOModal.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
@protocol OAuthIODelegate <NSObject>
2626
- (void)didReceiveOAuthIOResponse:(OAuthIORequest *)request;
2727
- (void)didFailWithOAuthIOError:(NSError *)error;
28+
- (void)didReceiveOAuthIOCode:(NSString *)code;
29+
- (void)didAuthenticateServerSide:(NSString *)body andResponse:(NSURLResponse *) response;
30+
- (void)didFailAuthenticationServerSide:(NSString *)body andResponse:(NSURLResponse *)response andError:(NSError *)error;
2831
@end
2932

3033
@interface OAuthIOModal : UIViewController<UIWebViewDelegate>
@@ -43,15 +46,19 @@
4346
UIWebView *_browser;
4447
UINavigationBar *_navigationBar;
4548
NSUInteger _navigationBarHeight;
49+
4650

4751
}
48-
52+
@property NSMutableArray *saved_cookies;
4953
@property (weak) id<OAuthIODelegate> delegate;
54+
@property NSURLSession *session;
55+
@property NSString *authUrl;
5056

5157
- (id)initWithKey:(NSString *)key delegate:(id)delegate;
5258
- (id)initWithKey:(NSString *)key delegate:(id)delegate andOptions:(NSDictionary *) options;
5359
- (void)showWithProvider:(NSString *)provider;
5460
- (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options;
61+
- (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options stateTokenUrl:(NSString*) stateUrl authUrl:(NSString*) authUrl;
5562
- (BOOL) clearCache;
5663
- (BOOL) clearCacheForProvider:(NSString *)provider;
5764
- (BOOL) cacheAvailableForProvider:(NSString *)provider;

OAuthiOS/Src/OAuthIOModal.m

Lines changed: 89 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#import "OAuthIOModal.h"
1919

2020
@implementation OAuthIOModal
21-
2221
NSString *_host;
2322

2423
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
@@ -146,10 +145,63 @@ - (void)getTokens:(NSString *)url
146145
[data_to_file writeToFile:file_url atomically:YES];
147146
}
148147

148+
if (_saved_cookies != nil) {
149+
NSHTTPCookie *cookie;
150+
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
151+
for (cookie in _saved_cookies) {
152+
[storage setCookie:cookie];
153+
}
154+
[[NSUserDefaults standardUserDefaults] synchronize];
155+
}
156+
157+
149158
@try {
150159
OAuthIORequest *request = [self buildRequestObject:json];
151-
if ([self.delegate respondsToSelector:@selector(didReceiveOAuthIOResponse:)])
152-
[self.delegate didReceiveOAuthIOResponse:request];
160+
if ([[request getCredentials] objectForKey:@"code"] != nil && _authUrl != nil) {
161+
//Signing in to the selected URL, giving back the response
162+
163+
NSString *code = [[request getCredentials] objectForKey:@"code"];
164+
NSString *post = [NSString stringWithFormat:@"code=%@", code];
165+
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
166+
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];
167+
NSMutableURLRequest *state_request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:_authUrl]
168+
cachePolicy:NSURLRequestUseProtocolCachePolicy
169+
timeoutInterval:60.0];
170+
[state_request setHTTPMethod:@"POST"];
171+
[state_request setValue:postLength forHTTPHeaderField:@"Content-Length"];
172+
[state_request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
173+
[state_request setHTTPBody:postData];
174+
175+
[[_session dataTaskWithRequest:state_request
176+
completionHandler:^(NSData *data,
177+
NSURLResponse *response,
178+
NSError *error) {
179+
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
180+
NSString *body = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
181+
if ([httpResponse statusCode] == 200) {
182+
if ([self.delegate respondsToSelector:@selector(didAuthenticateServerSide:andResponse:)])
183+
[self.delegate didAuthenticateServerSide:body andResponse:response];
184+
} else {
185+
NSDictionary *userInfo = @{
186+
NSLocalizedDescriptionKey: NSLocalizedString(@"Operation was unsuccessful.", nil),
187+
NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"The authentication endpoint did not return 200 OK.", nil),
188+
NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(@"Are you using the right authentication endpoint?", nil)
189+
};
190+
NSError *error = [NSError errorWithDomain:@"com.oauthio.error"
191+
code:-1
192+
userInfo:userInfo];
193+
if ([self.delegate respondsToSelector:@selector(didFailAuthenticationServerSide:andResponse:andError:)])
194+
[self.delegate didFailAuthenticationServerSide:body andResponse:response andError:error];
195+
}
196+
}] resume];
197+
198+
} else if ([[request getCredentials] objectForKey:@"code"] != nil) {
199+
if ([self.delegate respondsToSelector:@selector(didReceiveOAuthIOCode:)])
200+
[self.delegate didReceiveOAuthIOCode:[[request getCredentials] objectForKey:@"code"]];
201+
}else {
202+
if ([self.delegate respondsToSelector:@selector(didReceiveOAuthIOResponse:)])
203+
[self.delegate didReceiveOAuthIOResponse:request];
204+
}
153205
}
154206
@catch (NSException *e) {
155207
NSMutableDictionary *errorDetail = [NSMutableDictionary dictionary];
@@ -251,6 +303,38 @@ - (void)showWithProvider:(NSString *)provider {
251303
[self showWithProvider:provider options:nil];
252304
}
253305

306+
- (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options stateTokenUrl:(NSString*) stateUrl authUrl:(NSString*) authUrl;
307+
{
308+
_session = [NSURLSession sharedSession];
309+
_authUrl = authUrl;
310+
[[_session dataTaskWithURL:[NSURL URLWithString:stateUrl]
311+
completionHandler:^(NSData *data,
312+
NSURLResponse *response,
313+
NSError *error) {
314+
NSString *body = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
315+
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
316+
if (dictionary != nil && [dictionary objectForKey:@"token"] != nil) {
317+
318+
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
319+
NSMutableDictionary *options_mut = [options mutableCopy];
320+
[options_mut setObject:[dictionary objectForKey:@"token"] forKey:@"state"];
321+
[self showWithProvider:provider options:options_mut];
322+
} else {
323+
NSDictionary *userInfo = @{
324+
NSLocalizedDescriptionKey: NSLocalizedString(@"Operation was unsuccessful.", nil),
325+
NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"The state token could not be retrieved.", nil),
326+
NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(@"Are you using the right state token retrieval endpoint?", nil)
327+
};
328+
NSError *error = [NSError errorWithDomain:@"com.oauthio.error"
329+
code:-1
330+
userInfo:userInfo];
331+
if ([self.delegate respondsToSelector:@selector(didFailAuthenticationServerSide:andResponse:andError:)])
332+
[self.delegate didFailAuthenticationServerSide:body andResponse:response andError:error];
333+
}
334+
335+
}] resume];
336+
}
337+
254338
- (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options
255339
{
256340
_options = options;
@@ -293,11 +377,12 @@ - (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options
293377

294378
NSURLRequest *url = [_oauth getOAuthRequest:provider andUrl:_callback_url andOptions:options];
295379
if ([[_options objectForKey:@"clear-popup-cache"] isEqual: @"true"]) {
296-
// [[NSURLCache sharedURLCache] removeAllCachedResponses];
297380
NSHTTPCookie *cookie;
298381
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
382+
_saved_cookies = [[NSMutableArray alloc] init];
299383
for (cookie in [storage cookies]) {
300384
[storage deleteCookie:cookie];
385+
[_saved_cookies addObject:cookie];
301386
}
302387
[[NSUserDefaults standardUserDefaults] synchronize];
303388
}

README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,42 @@ You can filter the fields returned by this method by passing a `NSArray` contain
218218
}];
219219
```
220220

221+
Notes on the server-side flow
222+
=============================
223+
224+
If you're planning to use OAuth.io from your back-end thanks to one of our server-side SDKs, the usage of this SDK is a bit different.
225+
226+
First, a little reminder of the server-side flow, in which all API calls are performed server-side, as well as authentication (thanks to a code retrieved in the front-end). The server-side flow involves the following steps:
227+
228+
- Retrieving of a state token from your back-end in your front-end
229+
- Launching the authentication popup in the front-end, with the state token, gives back a code
230+
- Sending the code back to the back-end
231+
- Authenticating in the back-end thanks to the code
232+
- Performing API calls in the back-end
233+
234+
Thus, in your back-end, you need two endpoints:
235+
236+
- one for the state token (GET)
237+
- one for the authentication (POST with the code as parameter)
238+
239+
In the iOS SDK, the calls to these endpoints are performed automatically. All you need to do is give their URLs to the `showWithProvider` method like this:
240+
241+
```Objective-C
242+
[_oauthioModal showWithProvider:@"facebook" options:options stateTokenUrl:@"http://example/state/url" authUrl:@"http://example/auth/url"];
243+
```
244+
245+
This will first call the state URL, then show the authentication popup to the user, get the code, and finally send the code to the authentication URL.
246+
247+
To know when the process is done, you need to add the following methods to your OAuthIODelegate class:
248+
249+
```Objective-C
250+
- (void)didAuthenticateServerSide:(NSString *)body andResponse:(NSURLResponse *) response;
251+
- (void)didFailAuthenticationServerSide:(NSString *)body andResponse:(NSURLResponse *)response andError:(NSError *)error;
252+
```
253+
254+
The first one will catches a successfull authentication (which usually means the authentication URL returned "200 OK") and give you the body and response objects it got from that URL. The second one will catch errors (state token not found, unsucessfull authentication).
255+
256+
221257
Contributing
222258
============
223259

0 commit comments

Comments
 (0)