我有一个 Ruby on Rails 应用程序,它是 OAuth 2.0 提供者,这要归功于 Doorkeeper gem 并且有一个 API。我正在构建一个将与 API 交互的 iPhone 客户端;它使用 gtm-oauth2 库进行身份验证过程。
我完成了 OAuth 身份验证部分,因此用户可以将帐户添加到 iPhone 应用程序。现在我需要从 iPhone(或 iPhone 模拟器)钥匙串中检索授权,以与我的主应用程序的私有 API 进行交互。这是我拥有的代码:
GTMOAuth2Authentication *auth = [_db catapultAuthenticaiton];
[GTMOAuth2ViewControllerTouch authorizeFromKeychainForName:kCatapultKeychainItemName
authentication:auth];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://api.lvh.me:3000/api/clients/%@", accountName]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
GTMHTTPFetcher *fetcher = [GTMHTTPFetcher fetcherWithRequest:request];
[fetcher setAuthorizer:auth];
[fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) {
if (error != nil) {
#if DEBUG
NSLog(@"Error fetching client: %@", error);
#endif
}
}];
在 fetcher 完成处理程序中,当我尝试从钥匙串检索现有授权并对服务器执行 API 调用时,我收到 401 invalid_request 错误:
2013-04-02 11:08:55.546 Catapult for iOS[31776:c07] Error Error Domain=com.google.HTTPStatus Code=401 "The operation couldn’t be completed. (com.google.HTTPStatus error 401.)" UserInfo=0x7248010 {data=<7b226572 726f7222 3a22696e 76616c69 645f7265 71756573 74222c22 6572726f 725f6465 73637269 7074696f 6e223a22 54686520 72657175 65737420 6973206d 69737369 6e672061 20726571 75697265 64207061 72616d65 7465722c 20696e63 6c756465 7320616e 20756e73 7570706f 72746564 20706172 616d6574 65722076 616c7565 2c206f72 20697320 6f746865 72776973 65206d61 6c666f72 6d65642e 227d>}
Error data:
{
error = "invalid_request";
"error_description" = "The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.";
}
2013-04-02 11:08:55.546 Catapult for iOS[31776:c07] Error fetching client: Error Domain=com.google.HTTPStatus Code=401 "The operation couldn’t be completed. (com.google.HTTPStatus error 401.)" UserInfo=0x725bf00 {data=<7b226572 726f7222 3a22696e 76616c69 645f7265 71756573 74222c22 6572726f 725f6465 73637269 7074696f 6e223a22 54686520 72657175 65737420 6973206d 69737369 6e672061 20726571 75697265 64207061 72616d65 7465722c 20696e63 6c756465 7320616e 20756e73 7570706f 72746564 20706172 616d6574 65722076 616c7565 2c206f72 20697320 6f746865 72776973 65206d61 6c666f72 6d65642e 227d>, json={
error = "invalid_request";
"error_description" = "The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.";
}}
我使用 GTMHTTPFetcherLogging 来记录发出的 HTTP 请求,这是记录的内容:
refresh token for oauth.lvh.me
2013-04-02 10:08:55 +0000
Request: POST https://oauth.lvh.me:3000/oauth/token
Request headers:
Content-Type: application/x-www-form-urlencoded
User-Agent: gtm-oauth2 com.catapult.Catapult-for-iOS/1.0
Request body: (257 bytes)
client_id=b29a572c2caa218b8591011e1cc67f0f3536ffe4c449ab7b806dd4d363681401&client_secret=_snip_&grant_type=refresh_token&refresh_token=_snip_
Response: status 401
Response headers:
Cache-Control: no-store
Connection: close
Content-Type: application/json; charset=utf-8
Pragma: no-cache
Server: thin 1.5.1 codename Straight Razor
Strict-Transport-Security: max-age=31536000
X-Request-Id: 65b11f0a4fc06fa5562332252fd6cdcd
X-Runtime: 0.212716
X-UA-Compatible: IE=Edge
Response body: (162 bytes)
{
"error_description" : "The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.",
"error" : "invalid_request"
}
-----------------------------------------------------------
这是服务器的日志:
Started POST "/oauth/token" for 127.0.0.1 at 2013-04-02 11:08:55 +0100
Doorkeeper::AccessToken Load (0.2ms) SELECT "oauth_access_tokens".* FROM "oauth_access_tokens" WHERE "oauth_access_tokens"."refresh_token" = 'ddb0a1bd3256e351ff7081300dc7ac73035e897ea93d36053b7fb87843015a51' LIMIT 1
Doorkeeper::Application Load (0.1ms) SELECT "oauth_applications".* FROM "oauth_applications" WHERE "oauth_applications"."uid" = 'b29a572c2caa218b8591011e1cc67f0f3536ffe4c449ab7b806dd4d363681401' AND "oauth_applications"."secret" = 'b0de316c20112708d04284f6867f5bb51c1d20c72415642b38f09a8faca966cd' LIMIT 1
当请求有效时,服务器的日志如下所示:
Started POST "/oauth/token" for 127.0.0.1 at 2013-04-02 11:19:19 +0100
Doorkeeper::AccessGrant Load (0.2ms) SELECT "oauth_access_grants".* FROM "oauth_access_grants" WHERE "oauth_access_grants"."token" = '4391e187a0df16c56d1e6b16bf51340af8d677dbf625c495f50a249678e0502e' LIMIT 1
Doorkeeper::Application Load (0.1ms) SELECT "oauth_applications".* FROM "oauth_applications" WHERE "oauth_applications"."uid" = 'b29a572c2caa218b8591011e1cc67f0f3536ffe4c449ab7b806dd4d363681401' AND "oauth_applications"."secret" = 'b0de316c20112708d04284f6867f5bb51c1d20c72415642b38f09a8faca966cd' LIMIT 1
SQL (1.0ms) UPDATE "oauth_access_grants" SET "revoked_at" = '2013-04-02 10:19:19' WHERE "oauth_access_grants"."id" = 7
Doorkeeper::AccessToken Load (0.2ms) SELECT "oauth_access_tokens".* FROM "oauth_access_tokens" WHERE "oauth_access_tokens"."application_id" = 1 AND "oauth_access_tokens"."resource_owner_id" = 266 AND "oauth_access_tokens"."revoked_at" IS NULL ORDER BY created_at desc LIMIT 1
所以这里显然有问题......我不知道问题是来自服务器还是iOS客户端,但我的直觉告诉我它来自客户端。
请问有什么线索吗?