问题描述
我一整天都在为这件事头疼.
I've been breaking my head over this the whole day.
我希望将我的 iOS 应用程序与 Withings api 集成.它使用 OAuth 1.0,我似乎无法完全理解如何实现它.
I wish to integrate my iOS app with Withings api. It uses OAuth 1.0 and I can't seem to understand fully how to implement it.
我一直在下载多个 OAuth 框架(MPOAuth、gtm-oauth,ssoauthkit) 但无法完全弄清楚我应该做什么.
I've been downloading multiple OAuth framworks (MPOAuth,gtm-oauth,ssoauthkit) but couldn't figure out completely what exactly I should do.
我搜索了很多,也在堆栈溢出中搜索了有关如何在一般情况下实施 OAuth 1.0 的良好参考.尤其是与 Withings 集成但没有成功.
I searched a lot, also in stack overflow for good references on how to go about implementing OAuth 1.0 in general & integrating with Withings in particular with no success.
请解释将 iOS 应用与需要 OAuth 1.0 的 API 集成的流程.代码示例将非常有帮助.建议的第 3 方框架也不错.
Kindly explain the flow of integrating an iOS app with an api that requires OAuth 1.0. Code examples would be very helpful. Suggested 3rd party frameworks would be nice too.
澄清一下,我完全理解 OAuth 1.0 原则,只是在我的应用中实际实现它时遇到了问题.
Just to clarify, I fully understand the OAuth 1.0 principles, I just have problems in actually implementing it in my app.
我认为包含代码示例和良好参考资料的详尽答案对很多人都非常有帮助,因为我找不到.如果有人在实施方面有很好的经验,请花时间分享.
I think that a thorough answer with code examples and good references would be very helpful for lots of people as I couldn't find one. If anyone has good experience with implementing it, please take the time to share it.
推荐答案
TDOAuth 在我看来是最佳解决方案.它干净简单,只有一个 .h 和 .m 文件可供使用,没有复杂的示例项目..
TDOAuth in my opinion was the best solution. it is clean and simple, only one .h and .m file to work with, and no complicated example projects..
这是 OAuth 1.0 流程:
This is the OAuth 1.0 flow:
第 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 委托方法将处理回调..)
step 2 - get authorize token (by loading the request in a UIWebView, the webViewDidFinishLoad delegate method will handle the call back..)
//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 闻起来很臭,但它可以完成工作,应该重构它..)
handle the webView as follow to initiate step 3 (I know the isAuthorizeCallBack smells a lot, but it does the job, should refactor it..)
- (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"]];
}
这篇关于在 iOS 应用中实现 OAuth 1.0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!