使用Restkit消耗2 Legged OAuth身份validation(或)使用者密钥OAuth Web服务

我已按照本指南在我的网站中配置了2条腿OAuth服务: http : //drupal.org/node/1827698

我很确定配置是正确的,因为当我通过Web浏览器使用基本URL +服务端点触发web服务时,浏览器会返回以下错误:

This XML file does not appear to have any style information associated with it. The document tree is shown below. The request must be signed 

哪种情况表明它是一种身份validation错误。 我想。

现在我有计划在我的iPhone项目中使用Restkit。 我按照本指南写下了一个简单的2脚OAuth Web服务请求: https : //github.com/RestKit/RestKit/wiki/OAuth-Support-on-RestKit

这是我的代码:

  NSString *urlResource = @""; urlResource = @"/service_endpoint/node"; RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURLString:@"http://mydomain.com/"]; [RKObjectManager setSharedManager:objectManager]; objectManager.client.OAuth1ConsumerKey = @"proper_consumer_key"; objectManager.client.OAuth1ConsumerSecret = @"proper_consumer_secret"; objectManager.client.OAuth1AccessToken = nil; objectManager.client.OAuth1AccessTokenSecret = nil; objectManager.client.authenticationType = RKRequestAuthenticationTypeOAuth1; #define USE_GET_REQUEST 0 #if USE_GET_REQUEST [objectManager.client get:urlResource delegate:self]; #else NSDictionary *theParams = nil; NSString *timeStamp = [[NSNumber numberWithInt:(NSTimeInterval)[[NSDate date] timeIntervalSince1970]] stringValue]; theParams = [NSDictionary dictionaryWithObjectsAndKeys:@"1.0", @"oauth_version", @"HMAC-SHA1", @"oauth_signature_method", timeStamp, @"oauth_timestamp", nil]; [objectManager.client post:urlResource params:theParams delegate:self]; #endif 

如post中所示,我之前尝试过GET请求。 我得到一个没有任何数据的空体,Restkit记录这个,这表明授权问题:

2012-11-06 19:27:46.887 MyProject OAuth [22187:11603]我restkit.network:RKRequest.m:689状态代码:401

我意识到Restkit不会以这种方式添加任何参数,因此请求不知道要使用什么签名,时间戳和OAuth版本。 因此我尝试使用POST请求,我可以指定这些参数。 即使现在我得到一个空的身体,Restkit日志说:

2012-11-06 19:28:03.231 MyProject OAuth [22205:11603]我restkit.network:RKRequest.m:689状态代码:404

我不知道我哪里出错或者还有什么可尝试的! 期待在解决此问题时提供帮助。

编辑:我实现了一个缺少回调的方法,现在我得到:

“请求必须签署”

信息。 我认为上面的设置应该足够用于OAuth身份validation,如引用链接中所述,我还应该做些什么?

观察

我可以看到RestKit代码的内部结构和OAuth参数被放入URL请求的HTTP头字段中。 但我不确定Drupal 7是否能够从HTTP头字段读取此信息,因为它始终会返回给我:

请求必须签名

这意味着Drupal在第一种情况下没有收到OAuth参数,否则它至少会给我以下错误:

签名无效

我正在寻找一些其他选项来查看我的消费者密钥和密钥以及所有其他设置是否在服务器端正确完成。 为了确认这一点,我从这里下载了php OAuth客户端脚本。 从这里下载SVN代码。 当我用PHP客户端交叉检查请求时,我的请求都得到了完美的服务,我只需输入端点,消费者密钥和消费者密钥就可以获得xml。

我尝试的另一件事是允许GCOAuth生成签名,并在Restkit内部放置一个断点,以便我可以在日志中转储HTTP头字段,而不是Restkit将请求发送到服务器,我快速准备了URL请求与上述PHP客户端完全相同的格式。 现在这个请求被触发后,我回来了

签名无效

响应,这是否也意味着在Restkit / GCOAuth中没有正确准备OAuth参数?

谢谢,拉吉

我能够通过在Restkit的类中进行更改来解决它。 根据我在上面问题中提到的观察结果,我能够弄清楚我认为是某些网络服务器的限制,在这种情况下我们可以说是Drupal 7。 几乎在我遇到的所有OAuth库中,OAuth身份validation参数都在请求的HTTP头字段中设置。

我遇到了PHP客户端 (如我在上面的观察中所提到的),如果我们提供正确的消费者密钥和消费者密钥,它将生成oauth_nonce字符串,时间戳并且还将在URL的查询参数内提供oauth_signature。 Restkit的库中缺少此function(我假设?)。 虽然Restkit使用GCOAuth提供的所有信息填充HTTP头字段,但我觉得我的Drupal 7网络服务器没有以某种方式读取它,或者我使用了错误的密钥用于HTTP头字段。 我搜索了Drupal 7的文档,关于如何在HTTP头字段中传递参数并从那里读取它,但是我找不到太多的帮助而且不是那么精通它。

所以我的解决方案就是像提到的PHP客户端那样构建URL请求。 几乎所有内容都由Restkit在GCOAuth类,RKClient和RKRequest类中完成。 我所要做的就是调整以便将OAuth参数附加到请求URL。 我所有的更改都推到了github上的Restkit的分叉代码中 。 我对此OAuth模块的具体更改使用“// Raj OAuth:”进行了注释,可以在项目中进行搜索。

下面是我成功用于触发和使用Web服务的代码。 现在我已经为RKClient的-get:delegate:方法提供了一个重载的指定方法,我相信可以根据需要扩展到所有其他可用方法。

 -(void)triggerOAuthRequest { NSString *urlResource = @""; urlResource = @"/endpoint_path/endpoint.xml"; NSString *baseURL = @"http://your_domain_name.com/path_to_drupal_home_folder/"; NSString *consumerKey = @"YW9h6tUc*************"; NSString *consumerSecret = @"HUS2ALAC*************"; RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURLString:baseURL]; [RKObjectManager setSharedManager:objectManager]; objectManager.client.OAuth1ConsumerKey = consumerKey; objectManager.client.OAuth1ConsumerSecret = consumerSecret; objectManager.client.OAuth1AccessToken = nil; objectManager.client.OAuth1AccessTokenSecret = nil; objectManager.client.authenticationType = RKRequestAuthenticationTypeOAuth1; [objectManager.client get:urlResource delegate:self constructOAuthQueryParamsInURL:YES]; } 

我还假设发送此请求足够安全,因为我的OAuth参数在客户端使用密钥消费者密钥签名,然后将请求发送到服务器,尽管URL本身具有查询参数,我觉得它是安全的,因为oauth_signature是使用秘密消费者密钥签名的,只有网络服务器可以解密并检查请求是否来自真实来源。

如果您觉得有任何改进的余地,请告诉我。

谢谢,

拉吉