在iOS应用中实现OAuth 1.0

我一整天都在为此而头痛。

我希望将我的iOS应用程序与Withings api集成。 它使用OAuth 1.0,我似乎无法完全理解如何实现它。

我一直在下载多个OAuth framworks( MPOAuth , gtm-oauth , ssoauthkit ),但无法完全弄清楚我应该做什么。

我search了很多,也在堆栈溢出,以便如何在一般情况下实现OAuth 1.0以及与Withings集成,尤其是没有成功。

请解释一下将iOS应用程序与需要OAuth 1.0的api集成的stream程。 代码示例会非常有帮助。 build议的第三方框架也不错。

只是为了澄清,我完全理解OAuth 1.0的原则,我只是在我的应用程序中实际执行它的问题。

我认为,通过代码示例和很好的参考资料的彻底回答将是很多人,因为我找不到一个很有帮助。 如果有人有很好的实施经验,请花时间分享。

TDOAuth在我看来是最好的解决scheme。 它干净而简单,只有一个.h和.m文件可以使用,而且没有复杂的示例项目。

这是OAuth 1.0stream程:

第1步 – 获取请求令牌

//withings additional params NSMutableDictionary *dict = [NSMutableDictionary dictionary]; [dict setObject:CALL_BACK_URL forKey:@"oauth_callback"]; //init request NSURLRequest *rq = [TDOAuth URLRequestForPath:@"/request_token" GETParameters:dict scheme:@"https" host:@"oauth.withings.com/account" consumerKey:WITHINGS_OAUTH_KEY consumerSecret:WITHINGS_OAUTH_SECRET accessToken:nil tokenSecret:nil]; //fire request NSURLResponse* response; NSError* error = nil; NSData* result = [NSURLConnection sendSynchronousRequest:rq returningResponse:&response error:&error]; NSString *s = [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding]; //parse result NSMutableDictionary *params = [NSMutableDictionary dictionary]; NSArray *split = [s componentsSeparatedByString:@"&"]; for (NSString *str in split){ NSArray *split2 = [str componentsSeparatedByString:@"="]; [params setObject:split2[1] forKey:split2[0]]; } token = params[@"oauth_token"]; tokenSecret = params[@"oauth_token_secret"]; 

第2步 – 获取授权令牌 (通过在UIWebView中加载请求,webViewDidFinishLoad委托方法将处理callback..)

 //withings additional params NSMutableDictionary *dict2 = [NSMutableDictionary dictionary]; [dict setObject:CALL_BACK_URL forKey:@"oauth_callback"]; //init request NSURLRequest *rq2 = [TDOAuth URLRequestForPath:@"/authorize" GETParameters:dict2 scheme:@"https" host:@"oauth.withings.com/account" consumerKey:WITHINGS_OAUTH_KEY consumerSecret:WITHINGS_OAUTH_SECRET accessToken:token tokenSecret:tokenSecret]; webView.delegate = self; [DBLoaderHUD showDBLoaderInView:webView]; [webView loadRequest:rq2]; 

处理webView如下启动步骤3 (我知道isAuthorizeCallBack闻了很多,但它的工作,应该重构它..)

 - (void)webViewDidFinishLoad:(UIWebView *)aWebView { [DBLoaderHUD hideDBLoaderInView:webView]; NSString *userId = [self isAuthorizeCallBack]; if (userId) { //step 3 - get access token [DBLoaderHUD showDBLoaderInView:self.view]; [self getAccessTokenForUserId:userId]; } //ugly patchup to fix an invalid token bug if ([webView.request.URL.absoluteString isEqualToString:@"http://oauth.withings.com/account/authorize?"]) [self startOAuthFlow]; } - (NSString *)isAuthorizeCallBack { NSString *fullUrlString = webView.request.URL.absoluteString; if (!fullUrlString) return nil; NSArray *arr = [fullUrlString componentsSeparatedByString:@"?"]; if (!arr || arr.count!=2) return nil; if (![arr[0] isEqualToString:CALL_BACK_URL]) return nil; NSString *resultString = arr[1]; NSArray *arr2 = [resultString componentsSeparatedByString:@"&"]; if (!arr2 || arr2.count!=3) return nil; NSString *userCred = arr2[0]; NSArray *arr3 = [userCred componentsSeparatedByString:@"="]; if (!arr3 || arr3.count!=2) return nil; if (![arr3[0] isEqualToString:@"userid"]) return nil; return arr3[1]; } - (void)startOAuthFlow { [self step1]; [self step2]; } 

最后 – 第3步 – 获取访问令牌

 - (void)getAccessTokenForUserId:(NSString *)userId { //step 3 - get access token //withings additional params NSMutableDictionary *dict = [NSMutableDictionary dictionary]; [dict setObject:CALL_BACK_URL forKey:@"oauth_callback"]; [dict setObject:userId forKey:@"userid"]; //init request NSURLRequest *rq = [TDOAuth URLRequestForPath:@"/access_token" GETParameters:dict scheme:@"https" host:@"oauth.withings.com/account" consumerKey:WITHINGS_OAUTH_KEY consumerSecret:WITHINGS_OAUTH_SECRET accessToken:token tokenSecret:tokenSecret]; //fire request NSURLResponse* response; NSError* error = nil; NSData* result = [NSURLConnection sendSynchronousRequest:rq returningResponse:&response error:&error]; NSString *s = [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding]; //parse result NSMutableDictionary *params = [NSMutableDictionary dictionary]; NSArray *split = [s componentsSeparatedByString:@"&"]; for (NSString *str in split){ NSArray *split2 = [str componentsSeparatedByString:@"="]; [params setObject:split2[1] forKey:split2[0]]; } [self finishedAthourizationProcessWithUserId:userId AccessToken:params[@"oauth_token"] AccessTokenSecret:params[@"oauth_token_secret"]]; } 

我另外在这里保存请求标题

 NSMutableDictionary *dict2 = [NSMutableDictionary dictionary]; [dict2 setObject:CALL_BACK_URL forKey:@"oauth_callback"]; NSURLRequest *rq2 = [TDOAuth URLRequestForPath:@"/authorize" GETParameters:dict2 scheme:@"https" host:@"oauth.withings.com/account" consumerKey:WITHINGS_OAUTH_KEY consumerSecret:WITHINGS_OAUTH_SECRET accessToken:self.token tokenSecret:self.tokenSecret]; headers = rq2.allHTTPHeaderFields; 

而在callback方法中,我将添加缺less的参数到请求。 通过这样做,我避免了“丑陋的补丁修复”。

 - (BOOL)webView:(UIWebView *)wV shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ if (![request.allHTTPHeaderFields objectForKey:@"Authorization"] && [request.URL.absoluteString rangeOfString:@"acceptDelegation=true"].location == NSNotFound){ NSMutableURLRequest *mutableCp = [request mutableCopy]; NSLog(@"request :::%@", request); [mutableCp setAllHTTPHeaderFields:headers]; dispatch_async(dispatch_get_main_queue(), ^{ [webView loadRequest:mutableCp]; }); return NO; } return YES; } 

我希望它能帮助别人

我build议你检查这个项目既作为参考,也作为一个真正的工作OAuth类。 它inheritance了另一个伟大的项目,所以你需要添加你的两个。检查许可证是否适合你的要求。 https://github.com/rsieiro/RSOAuthEngine