Iphone 使用Restkit使用两条腿的OAuth身份验证(或)使用者密钥OAuth Web服务

Iphone 使用Restkit使用两条腿的OAuth身份验证(或)使用者密钥OAuth Web服务,iphone,ios,cocoa-touch,oauth,restkit,Iphone,Ios,Cocoa Touch,Oauth,Restkit,我已根据本指南在我的web中配置了两条腿的OAuth服务: 我非常确定配置是正确的,因为当我通过web浏览器使用基本URL+服务端点触发web服务时,浏览器会返回以下错误: This XML file does not appear to have any style information associated with it. The document tree is shown below. <result>The request must be signed</res

我已根据本指南在我的web中配置了两条腿的OAuth服务:

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

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<result>The request must be signed</result>
如中所示,我在前面尝试了GET请求。我得到一个没有任何数据的空主体,Restkit在某处记录了这一点,这表明授权问题:

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

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

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

我不知道我哪里出了问题,也不知道还能尝试什么!期待在解决此问题方面获得帮助

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

“必须对请求进行签名”

信息。我假设上面的设置对于OAuth身份验证已经足够了,正如在参考链接中提到的,我还应该做什么

观察结果:

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

请求必须签名

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

无效签名

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

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

无效签名

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

谢谢,
Raj

我能够通过修改Restkit的类来解决这个问题。根据我在上述问题中提到的观察结果,我能够找出我假设的某些Web服务器的限制,在本例中,让我们假设Drupal7。几乎在我为iOS遇到的所有OAuth库中,OAuth身份验证参数都是在请求的HTTP头字段中设置的

我遇到了(正如我在上面的观察中提到的),如果我们提供适当的使用者密钥和使用者机密,它将生成oauth_nonce字符串、时间戳,并且还将在URL的查询参数中提供oauth_签名。Restkit的库中缺少这种功能(我想是吧?)。尽管Restkit使用GCOAuth提供的所有信息填充HTTP头字段,但我觉得我的drupal7webserver没有以某种方式读取它,或者可能我对HTTP头字段使用了错误的键。我搜索了Drupal7中关于如何在HTTP头字段中传递参数的文档,并从中读取了它,但是我找不到太多的帮助,也不是很精通

因此,我的解决方案是按照前面提到的方法构建URL请求。几乎所有的事情都是由GCOAuth类、RKClient和RKRequest类中的Restkit完成的。我所要做的就是调整,以便将OAuth参数附加到请求URL。我所有的改变都推到了一个新的高度。我对这个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_签名是用秘密使用者密钥签名的,只有Web服务器才能解密并检查请求是否来自真实来源

如果你觉得还有改进的余地,请告诉我

谢谢

拉吉

-(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];
}