I have a Ruby on Rails application which is an OAuth 2.0 provider thanks to the Doorkeeper gem and has an API. I am building an iPhone client that will interact with the API; it uses the gtm-oauth2 library for the authentication process.
I finished the OAuth authentication part, so a user can add an account to the iPhone app. Now I need to retrieve the authorization from the iPhone (or iPhone Simulator) keychain to interact with the private API of my main application. Here is the code that I have:
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
}
}];
In the fetcher completion handler I am getting a 401 invalid_request error when trying to retrieve an existing authorization from the keychain and doing an API call to the server:
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.";
}}
I used GTMHTTPFetcherLogging to log the HTTP request made and here is what was logged:
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"
}
-----------------------------------------------------------
And here are the server's logs:
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
When the request works, here is how the server's logs look like:
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
So there is clearly something wrong here... I don't know if the problem comes from the server or the iOS client, but my guts tell me it comes from the client.
Any clues on what is happening please?
Related
I have been able to authenticate with the Pinterest API on both the javascript and Android SDK. On iOS, I've triple-checked all of my settings to make sure I've configured everything according to the documentation.
However, when I log in through iOS, I am taken to the Pinterest app to authorize and all looks good. However, when Pinterest passes me back to my app, I am getting the following login error:
Error Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: unauthorized (401)" UserInfo={com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x17403dea0> { URL: https://api.pinterest.com/v1/oauth/inspect?access_token=AYalMni-yTq5Y0UihwETrFxZpzL5FK2tXvfmkbhDyJ_OP8BGeQAAAAA&token=AYalMni-yTq5Y0UihwETrFxZpzL5FK2tXvfmkbhDyJ_OP8BGeQAAAAA } { status code: 401, headers {
Age = 0;
"Cache-Control" = private;
Connection = "keep-alive";
"Content-Length" = 177;
"Content-Type" = "application/json";
Date = "Mon, 20 Mar 2017 19:21:15 GMT";
"Pinterest-Generated-By" = "devplatform-devapi-prod-0a01239b";
"Pinterest-Version" = 918ef75;
"X-Content-Type-Options" = nosniff;
"X-Pinterest-RID" = 280542321780;
} }, NSErrorFailingURLKey=https://api.pinterest.com/v1/oauth/inspect?access_token=AYalMni-yTq5Y0UihwETrFxZpzL5FK2tXvfmkbhDyJ_OP8BGeQAAAAA&token=AYalMni-yTq5Y0UihwETrFxZpzL5FK2tXvfmkbhDyJ_OP8BGeQAAAAA, com.alamofire.serialization.response.error.data=<7b227374 61747573 223a2022 6661696c 75726522 2c202263 6f646522 3a20332c 2022686f 7374223a 20226465 76706c61 74666f72 6d2d6465 76617069 2d70726f 642d3061 30313233 3962222c 20226765 6e657261 7465645f 6174223a 20224d6f 6e2c2032 30204d61 72203230 31372031 393a3231 3a313520 2b303030 30222c20 226d6573 73616765 223a2022 41757468 6f72697a 6174696f 6e206661 696c6564 2e222c20 22646174 61223a20 6e756c6c 7d>, NSLocalizedDescription=Request failed: unauthorized (401)}
I tried taking the access token referred to in the error response and using the token debugger on the Pinterest developer site to check it, but when I did so I got the message "An error occurred. Please try again."
So, I'm stumped. It seems to me that the access token that's being generated on iOS login is being seen as invalid by Pinterest, but I don't know how to fix that.
Do you have any thoughts on what can be done to resolve this?
Im getting this error while posting image to Pinterest
Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: unauthorized (401)" UserInfo={com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x144603bd0> { URL: https://api.pinterest.com/v1/pins/ } { status code: 401, headers {
"Accept-Ranges" = bytes;
"Cache-Control" = private;
Connection = close;
"Content-Length" = 177;
"Content-Type" = "application/json";
Date = "Sun, 10 Jul 2016 19:38:00 GMT";
"Pinterest-Generated-By" = "devplatform-devapi-prod-de3d740a";
"Pinterest-Version" = bcdafd3;
Server = nginx;
"X-Content-Type-Options" = nosniff;
"X-Pinterest-RID" = 480720869025;
"X-Varnish" = 2958547338;
} }, NSErrorFailingURLKey=https://api.pinterest.com/v1/pins/, com.alamofire.serialization.response.error.data=<7b227374 61747573 223a2022 6661696c 75726522 2c202263 6f646522 3a20332c 2022686f 7374223a 20226465 76706c61 74666f72 6d2d6465 76617069 2d70726f 642d6465 33643734 3061222c 20226765 6e657261 7465645f 6174223a 20225375 6e2c2031 30204a75 6c203230 31362031 393a3338 3a303020 2b303030 30222c20 226d6573 73616765 223a2022 41757468 6f72697a 6174696f 6e206661 696c6564 2e222c20 22646174 61223a20 6e756c6c 7d>, NSLocalizedDescription=Request failed: unauthorized (401)}
Here is my code:
PDKClient.sharedInstance().createPinWithImage(image, link: NSURL(string:"http://domain"), onBoard: "MyBoard", description: caption, progress: {percent in
print(percent)
}, withSuccess: {PDKResponseObject in
print("ok")
print(PDKResponseObject.boards())
}, andFailure: {error in
print(error)
})
Error 401 means one of the following.
1.Authentication failed.
2.Authorization failed.
3.You are not permitted to access that resource.
Double check your permissions, check your session token expired or not.
So I think that there is nothing wrong with your code, or the request. It's something with the permissions you have in your Pinterest app.
Try changing the request URL from http to https.
Check the parameters you sending to Pinterest, check whether the parameter names are correct or not, as specified in Pinterest documentation. Also those parameters has the proper type of data, I mean do not pass String in the place of Integer value.
.
I have one issue facebook signing with quickblox api.
After getting AccessToken by using FBSDK.
[QBRequest logInWithSocialProvider:#"facebook" accessToken:accessToken accessTokenSecret:nil successBlock:^(QBResponse *response, QBUUser *user) {
} errorBlock:^(QBResponse *response) {}
i think facebook returns correct token string.
CAAVS4qDIQb4BAMS7pTl3P1EmtW1ZCOOpbTCQFWrBI8QsA7ufOTYapjF3rEpW1ojZChgOZB7mj6AWDocDSdtxFbksqP3FyZCIou6bUC6ON4ZCRFGPes6TBzufh68A9fBSSz6baTYCZCTIyZAoDhYdBZAvrHF3609cAiEZCesnWrtqYleqPv7YHIadrWf2x1oWItypF3V3pbDgsHd7MSSCcZBvK4yuHGeCUvf7qMPFznuRZCfwNCOcQBDU8ynHnzDPpnnhLEZD
[logInWithSocialProvider: accessToken: ...] function returns following error
[QBResponse], status: 422
2015-12-09 14:27:27.049 NudgeBuddies[2598:124844] [QBCore] Response error: Error Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: client error (422)" UserInfo={com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x7ffde266ce40> { URL: https://api.quickblox.com/login.json } { status code: 422, headers {
"Access-Control-Allow-Origin" = "*";
"Cache-Control" = "no-cache";
Connection = "keep-alive";
"Content-Length" = 47;
"Content-Type" = "application/json; charset=utf-8";
Date = "Wed, 09 Dec 2015 06:27:26 GMT";
"QB-Token-ExpirationDate" = "2015-12-09 08:27:26 UTC";
"QuickBlox-REST-API-Version" = "0.1.1";
Server = "nginx/1.6.2";
Status = "422 Unprocessable Entity";
"X-Rack-Cache" = "invalidate, pass";
"X-Request-Id" = ab3443c24c0d5ee0a18d796eaf996cb7;
"X-Runtime" = "0.221723";
"X-UA-Compatible" = "IE=Edge,chrome=1";
} }, NSErrorFailingURLKey=https://api.quickblox.com/login.json, com.alamofire.serialization.response.error.data=<7b226572 726f7273 223a7b22 62617365 223a5b22 4c6f6769 6e206f72 20656d61 696c2072 65717569 72656422 5d7d7d>, NSLocalizedDescription=Request failed: client error (422)}
Please Help me.
How can i solve this problem?
Regards.
In QuickBlox SDK 2.6.5 we have improved stability and we have enabled detail logging so you are able to see the reasons why problem happens.
QuickBlox has open source project Q-municate with Facebook login and you can check it by yourself.
Thanks!
I receive this error when I tried to signup an account with the app im building. May I know what does this error means? Thank you!
BaseNetworkManager.m:164 Error Domain=AFNetworkingErrorDomain Code=-1011
"Expected status code in (200-299), got 500" UserInfo=0x16d30560
{NSLocalizedRecoverySuggestion=meta http-equiv="refresh" content="0;
url =websitelink.error.html"
AFNetworkingOperationFailingURLRequestErrorKey=NSMutableURLRequest: 0x16670d80> { URL: mywebsite/users.json }, NSErrorFailingURLKey=h mywebsite.com/users.json, NSLocalizedDescription=Expected status code in (200-299), got 500, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0x1669fe20> { URL: mywebsite.com/users.json } { status code: 500, headers {
Connection = "keep-alive";
"Content-Length" = 690;
"Content-Type" = "text/html; charset=utf-8";
Date = "Fri, 01 May 2015 12:37:44 GMT";
Server = Cowboy;
Status = "500 Internal Server Error";
Via = "1.1 vegur";
"X-Rack-Cache" = "invalidate, pass";
"X-Request-Id" = "tyud";
"X-Runtime" = "5.087065"; } }}
2015-05-01 20:37:45.002 appname[1677:60b] <BaseNetworkManager.m:165> (null)
The server is telling you
500 Internal Server Error
this means that the server has a problem that is not your fault. (unless you are the one who is responsible for the server.)
HTTP 200..299 means "ok"
HTTP 300..399 means "look somewhere else"
HTTP 400..499 means "there is a problem with your request." for example 404=file not found, 403=forbidden, etc.
HTTP 500..599 means "the server has a problem / is misconfigured"
see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html for more info.
I want to use AFNetworking to POST to sinatra project to get json data. AFNetwroking always get back 403 status code. But curl works as expect. Why?
Here is the error on Xcode:
<AFHTTPRequestOperation: 0x7ffd5da42780, state: isFinished, cancelled: NO request: <NSMutableURLRequest: 0x7ffd5d9591b0> { URL: http://127.0.0.1:9292/api/v1/events/new }, response: <NSHTTPURLResponse: 0x7ffd5b7b7030> { URL: http://127.0.0.1:9292/api/v1/events/new } { status code: 403, headers {
Connection = "Keep-Alive";
"Content-Length" = 69;
"Content-Type" = "application/json";
Date = "Fri, 23 Jan 2015 08:42:32 GMT";
Server = "WEBrick/1.3.1 (Ruby/2.1.5/2014-11-13)";
"X-Content-Type-Options" = nosniff;
} }>
Curl on terminal:
curl http://127.0.0.1:9292/api/v1/events/new
{"error_code":10001,"error_message":"need token or token is illegal"}%
IOS code doesn't work:
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:
[NSURL URLWithString:#"http://127.0.0.1:9292/"]];
[manager POST:#"api/v1/events/new"
parameters:nil
success:nil
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{DLog(#"%#",operation);}];
rackup log:
[2015-01-23 16:58:20] INFO WEBrick 1.3.1
[2015-01-23 16:58:20] INFO ruby 2.1.5 (2014-11-13) [x86_64-darwin14.0]
[2015-01-23 16:58:20] INFO WEBrick::HTTPServer#start: pid=14445 port=9292
127.0.0.1 - - [23/Jan/2015:16:58:36 +0800] "POST /api/v1/events/new HTTP/1.1" 403 69 0.0179
Actually it works right, my server side make a path filter, but here provide a way, sometime not only just print operation but also operation.responseObject which i got what i want.
{
"error_code" = 10001;
"error_message" = "need token or token is illegal";
}