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";
}
Related
When application is failed to login/authenticate successfully with restkit in first attempts due to wrong username or password, application never get success even with correct username and password, any help would be appreciated in this.
On login button i create the restkit instance and pass the information here is the code
func sendLoginRequest(userName:String,password:String){
let authenticate:String = String(format: "%#:%#", userName, password)
let plainData = (authenticate as NSString).dataUsingEncoding(NSUTF8StringEncoding)
let base64String = plainData!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
print(base64String)
headers = ["Authorization" : String(format: "Basic %#", base64String)]
self.webInterface = DFWebInterface.shareWebInterface(DFModel.sharedInstance.bMockServer)
self.webInterface?.sendRequest(nil,request: LOGIN.rawValue, nil,headers: headers as! [NSObject : AnyObject])
}
then initialize my web interface class
-(id)init:(NSString*)strURL :(BOOL)mockServer{
if(nil!=(sDFWebInterface=[super init])){
NSURL *baseURL = [NSURL URLWithString:strURL];
DFAFHTTPClient* client=[[DFAFHTTPClient alloc] initWithBaseURL:baseURL];
sDFWebInterface->rkobjmanagerDF = [[RKObjectManager alloc] initWithHTTPClient:client];
[RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class] forMIMEType:#"text/plain"];
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
}
return sDFWebInterface;
}
After initializing i create mapping and send post request
Everything works fine if application send correct credential very first time
Here is the log for second time fail even application passing correct credential
2016-02-11 12:07:44.242 MyProject[7033:94063] I restkit.network:RKObjectRequestOperation.m:150 POST 'https://myproject-dev.apps.mycompany-iot-cloud.com/api/v1/authenticate'
2016-02-11 12:07:45.215 MyProject[7033:95645] E restkit.network:RKObjectRequestOperation.m:551 Object request failed: Underlying HTTP request operation failed with error: Error Domain=org.restkit.RestKit.ErrorDomain Code=-1011 "Expected status code in (200), got 401" UserInfo={NSLocalizedRecoverySuggestion={"timestamp":"2016-02-11T06:37:45.103+0000","status":401,"error":"Unauthorized","message":"Failed authenticating with username and password","path":"/api/v1/authenticate"}, NSErrorFailingURLKey=https://myproject-dev.apps.mycompany-iot-cloud.com/api/v1/authenticate, AFNetworkingOperationFailingURLRequestErrorKey= { URL: https://myproject-dev.apps.mycompany-iot-cloud.com/api/v1/authenticate }, AFNetworkingOperationFailingURLResponseErrorKey= { URL: https://myproject-dev.apps.mycompany-iot-cloud.com/api/v1/authenticate } { status code: 401, headers {
"Cache-Control" = "no-cache, no-store, max-age=0, must-revalidate";
"Content-Length" = 171;
"Content-Type" = "application/json;charset=UTF-8";
Date = "Thu, 11 Feb 2016 06:37:44 GMT";
Expires = 0;
Pragma = "no-cache";
Server = "";
"Set-Cookie" = "VCAP_ID=7487ff5a5d1940b895d0459b91eaec009a55f1ebd2774084b28fc6d24cab0f01; Path=/; HttpOnly";
"Strict-Transport-Security" = "max-age=31536000 ; includeSubDomains";
"Www-Authenticate" = "Basic realm=\"DEEPFIELD\"";
"X-Application-Context" = "gateway-dev:dev,cloud:0";
"X-Cf-Requestid" = "b0f1e586-8b60-4413-646d-515dbbe1f097, 954fd628-3beb-4777-41be-4eb50221b808";
"X-Content-Type-Options" = nosniff;
"X-Frame-Options" = DENY;
"X-Xss-Protection" = "1; mode=block";
} }, NSLocalizedDescription=Expected status code in (200), got 401}
2016-02-11 12:07:45.216 DeepField[7033:95645] E restkit.network:RKObjectRequestOperation.m:215 POST 'https://myproject-dev.apps.mycompany-iot-cloud.com/api/v1/authenticate' (401 Unauthorized / 0 objects) [request=0.9732s mapping=0.0000s total=0.9869s]: Error Domain=org.restkit.RestKit.ErrorDomain Code=-1011 "Expected status code in (200), got 401" UserInfo={NSLocalizedRecoverySuggestion={"timestamp":"2016-02-11T06:37:45.103+0000","status":401,"error":"Unauthorized","message":"Failed authenticating with username and password","path":"/api/v1/authenticate"}, NSErrorFailingURLKey=https://myproject-dev.apps.mycompany-iot-cloud.com/api/v1/authenticate, AFNetworkingOperationFailingURLRequestErrorKey= { URL: https://myproject-dev.apps.mycompany-iot-cloud.com/api/v1/authenticate }, AFNetworkingOperationFailingURLResponseErrorKey= { URL: https://myproject-dev.apps.mycompany-iot-cloud.com/api/v1/authenticate } { status code: 401, headers {
"Cache-Control" = "no-cache, no-store, max-age=0, must-revalidate";
"Content-Length" = 171;
"Content-Type" = "application/json;charset=UTF-8";
Date = "Thu, 11 Feb 2016 06:37:44 GMT";
Expires = 0;
Pragma = "no-cache";
Server = "";
"Set-Cookie" = "VCAP_ID=7487ff5a5d1940b895d0459b91eaec009a55f1ebd2774084b28fc6d24cab0f01; Path=/; HttpOnly";
"Strict-Transport-Security" = "max-age=31536000 ; includeSubDomains";
"Www-Authenticate" = "Basic realm=\"myproject\"";
"X-Application-Context" = "gateway-dev:dev,cloud:0";
"X-Cf-Requestid" = "b0f1e586-8b60-4413-646d-515dbbe1f097, 954fd628-3beb-4777-41be-4eb50221b808";
"X-Content-Type-Options" = nosniff;
"X-Frame-Options" = DENY;
"X-Xss-Protection" = "1; mode=block";
} }, NSLocalizedDescription=Expected status code in (200), got 401}
2016-02-11 12:07:45.216 DeepField[7033:94063] Error from server in Post Request
I just set header again for restkit httpclient and it starts working.
RKObjectManager* rkobjmanagerDF;
[[rkobjmanager.HTTPClient defaultHeaders] setValue:#"application/json" forKey:#"Content-Type"];
[[rkobjmanagerDF.HTTPClient defaultHeaders] setValue:#"application/json" forKey:#"Accept"];
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!
From all I have read gzipped response data should be automatically decompressed by the NS URL loading system. I am using AFNetworking and a AFJSONResponseSerializer to handle requests to a custom backend. I have experimented with adding "Accept-Encoding" = gzip to my request headers, but it has had no effect. My response headers include:
"Content-Encoding" = gzip;
"Content-Length" = 179837;
"Content-Type" = "application/json";
I am making the request like this:
[[AFHTTPRequestOperationManager sharedClient]
GET:#"some/endpoint"
parameters:#{#"foo":#"bar"}
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Response data size %u", operation.responseData.length);
NSURL *outputURL = [[APP_DELEGATE applicationDocumentsDirectory] URLByAppendingPathComponent:#"data.gzip"];
[operation.responseData writeToURL:outputURL atomically:NO];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"ERROR [%d] [%#]", error.code, error.localizedDescription );
}];
When this runs the size of operation.responseData.length printed is what I expect. However, responseObject is nil when it should be an NSArray. I added the lines writing operation.responseData to test that the data received is what I expect. I can browse to data.gzip, uncompress it, and see my JSON.
It appears to me that the gzipped data received is not being automatically decompressed before my AFJSONResponseSerializer tries to handle it. Most of what I have found on Stackoverflow has either discussed how the decompression is automatic or suggested adding an "Accept-Encoding" = gzip header. Any suggestions would be appreciated.
Have you checked the output from the "custom backend" — use something like Charles Proxy which will let you see things like your response headers and raw content.
e.g. typical headers as shown in Charles:
HTTP/1.1 200 OK
Date Wed, 26 Nov 2014 22:25:33 GMT
Server Apache/2.2.24 (Unix) mod_hive/4.0 mod_ssl/2.2.24 OpenSSL/1.0.0-fips mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 mod_fcgid/2.3.6
X-Powered-By PHP/5.3.29
P3P CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"
Cache-Control no-cache
Pragma no-cache
Set-Cookie 4d3750fca133ae462ca26ca5a1cc0104=c7da991b30f53342846fff5ddaf3ea08; path=/
Cache-Control max-age=3600
Expires Wed, 26 Nov 2014 23:25:33 GMT
Host-Header 192fc2e7e50945beb8231a492d6a8024
Keep-Alive timeout=5, max=100
Connection Keep-Alive
Transfer-Encoding chunked
Content-Type text/html; charset=utf-8
i am posting the parameter in the web-service. using the below code. and i am getting the "Request failed: unacceptable (406) Error .I am not sure is im posting it right .
I tried posting the data using their key and value pair using POSTMAN chrome app . and it is working fine there.Not here pls suggest .i am using Afnetworking for the first time
[params setValue:self.txtUserName forKey:#"name"];
[params setValue:self.txtEmail forKey:#"mail"];
[params setValue:self.txtPass forKey:#"conf_mail"];
[params setValue:self.txtPass2 forKey:#"pass"];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:#"http://charlie.indivar.info/ministore/store-commerce/user/register"
parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error Retrieving Data"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}];
Below is the console log
Error: Error Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: unacceptable (406)" UserInfo=0x8deb400 {com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x8ddddf0> { URL: http://website.com/ministore/store-commerce/user/register } { status code: 406, headers {
"Cache-Control" = "no-cache, must-revalidate, post-check=0, pre-check=0";
Connection = "Keep-Alive";
"Content-Length" = 396;
"Content-Type" = "application/json";
Date = "Fri, 10 Oct 2014 07:06:40 GMT";
Etag = "\"1412924800\"";
Expires = "Sun, 19 Nov 1978 05:00:00 GMT";
"Keep-Alive" = "timeout=5, max=100";
"Last-Modified" = "Fri, 10 Oct 2014 07:06:40 +0000";
Server = Apache;
"Set-Cookie" = "SESSd5cd87b70f9ea9019d306d6f4e440b74=5lpY8-PvQYRM5IBWiGk33EeXsucAJCBZQSce7vRBhEY; expires=Sun, 02-Nov-2014 10:40:01 GMT; path=/; domain=website.com; HttpOnly";
Vary = Accept;
"X-Drupal-Cache" = MISS;
"X-Powered-By" = "PHP/5.3.10-1ubuntu3.14";
} }, NSErrorFailingURLKey=http://website.com/ministore/store-commerce/user/register, NSLocalizedDescription=Request failed: unacceptable (406), com.alamofire.serialization.response.error.data=
0a7b2273 74617475 73223a22 30222c22 64617461 223a7b22 6e616d65 223a2255 7365726e 616d6520 63616e6e
6f742062 65206c6f 6e676572 20746861 6e203630 20636861 72616374
65727320 62757420 69732063 75727265 6e746c79 20323031 20636861
72616374 65727320 6c6f6e67 2e222c22 6d61696c 223a2254 68652065
2d6d6169 6c206164 64726573 7320266c 743b5549 54657874 4669656c
643a2030 78386462 63306230 3b206672 616d6520 3d202835 37203135
343b2031 35332033 30293b20 74657874 203d2026 23303339 3b646565
70616b73 6f6f6440 64656570 616b2e63 6f6d2623 3033393b 3b20636c
69707354 6f426f75 6e647320 3d205945 533b206f 70617175 65203d20
4e4f3b20 6175746f 72657369 7a65203d 20524d2b 424d3b20 67657374
75726552 65636f67 6e697a65 7273203d 20266c74 3b4e5341 72726179
3a203078 38663665 38613026 67743b3b 206c6179 6572203d 20266c74
3b43414c 61796572 3a203078 38646165 65653026 67743b26 67743b20
6973206e 6f742076 616c6964 2e227d7d>}
If the Web server detects that the data it wants to return is not
acceptable to the client, it returns a header containing the 406 error
code. This error occurs very infrequently in Web browsers, because most browsers will accept any data returned from the Web server.
Looks like the server is not recognized that you are mobile etc...
http://www.checkupdown.com/status/E406.html
This is a very old question, BUT:
You need to read the response data send by the server, the "0a7b2273..." part.
There, if you do:
NSString *responseString = [[NSString alloc] initWithData:thatData encoding:NSUTF8StringEncoding];
You'll see that the value is (it's JSON, I just linted it):
{
"status": "0",
"data": {
"name": "Username cannot be longer than 60 characters but is currently 201 characters long.",
"mail": "The e-mail address <UITextField: 0x8dbc0b0; frame = (57 154; 153 30); text = 'deepaksood#deepak.com'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x8f6e8a0>; layer = <CALayer: 0x8daeee0>> is not valid."
}
}
Your error was that in:
[params setValue:self.txtUserName forKey:#"name"];
self.txtEmail is a UITextField, not the textField.text. So, it was either self.txtEmail.text, or at some point, you wrote self.txtEmail = textField instead of self.txtEmail = textField.text. I guess this was also the case for the userName.
• So, after so much time, what's the thing that can still be applied nowadays:
Read the returned value! If might contain useful information on why it failed. When debugging, grab as much info as possible: HTTP Code, values send/read/received, etc.
I am writing a simple application on iOS and I am trying to consume a RESTFull webservice
To have some tips and get some knowledge I first start with twitter without using ios integrated libs, but I always get stocked on Auth.
Any working sample or link will be appreciated, as reminder twitter is not my final goal
For instance this is one of my code, based on RestKit and AFOAuth1Client :
NSURL *url = [NSURL URLWithString:#"https://api.twitter.com"];
AFOAuth1Client * twitterClient = [[AFOAuth1Client alloc] initWithBaseURL:url key:kCLIENTID secret:kCLIENTSECRET];
[twitterClient authorizeUsingOAuthWithRequestTokenPath:#"oauth/request_token"
userAuthorizationPath:#"oauth/authorize"
callbackURL:[NSURL URLWithString:#"af-twitter://success"]
accessTokenPath:#"oauth/access_token"
accessMethod:#"POST"
scope:#""
success:^(AFOAuth1Token *token, id responseObject) {
}
failure:^(NSError *error) {
}];
as you can see it does not work :
2013-06-17 16:59:01.389 restKitTest[14490:c07] I restkit:RKLog.m:34 RestKit logging initialized...
2013-06-17 16:59:02.653 restKitTest[14490:c07] I restkit.network:RKObjectRequestOperation.m:174 POST 'http://api.twitter.com/oauth/request_token'
2013-06-17 16:59:03.051 restKitTest[14490:c07] E restkit.network:RKObjectRequestOperation.m:203 POST 'http://api.twitter.com/oauth/request_token' (401 Unauthorized) [0.3980 s]: Error Domain=AFNetworkingErrorDomain Code=-1011 "Expected status code in (200-299), got 401" UserInfo=0x9c96640 {NSLocalizedRecoverySuggestion=Failed to validate oauth signature and token, AFNetworkingOperationFailingURLRequestErrorKey=<NSMutableURLRequest: 0x9877e20> { URL: http://api.twitter.com/oauth/request_token }, NSErrorFailingURLKey=http://api.twitter.com/oauth/request_token, NSLocalizedDescription=Expected status code in (200-299), got 401, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0x9aac910> { URL: http://api.twitter.com/oauth/request_token } { status code: 401, headers {
"Cache-Control" = "no-cache, no-store, must-revalidate, pre-check=0, post-check=0";
"Content-Encoding" = gzip;
"Content-Length" = 62;
"Content-Type" = "text/html; charset=utf-8";
Date = "Mon, 17 Jun 2013 14:59:03 GMT";
Expires = "Tue, 31 Mar 1981 05:00:00 GMT";
"Last-Modified" = "Mon, 17 Jun 2013 14:59:03 GMT";
Pragma = "no-cache";
Server = tfe;
"Set-Cookie" = "_twitter_sess=BAh7CDoPY3JlYXRlZF9hdGwrCOJ3pVI%252FAToHaWQiJTIyYzUxN2UwNmUwYTI4%250AYzU1NmU0OTYxZDA5MDcwMmI3IgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVy%250AOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsA--3291687666d367b6ccddc74513532bf56ea144d9; domain=.twitter.com; path=/; HttpOnly, guest_id=v1%3A137148114312677519; Domain=.twitter.com; Path=/; Expires=Wed, 17-Jun-2015 14:59:03 UTC";
Status = "401 Unauthorized";
Vary = "Accept-Encoding";
"x-frame-options" = SAMEORIGIN;
"x-mid" = af106773611449e1226d5dd5d531b64d91e4f3f8;
"x-runtime" = "0.01153";
"x-transaction" = 24e58d8eb3b7cdb5;
"x-ua-compatible" = "IE=10,chrome=1";
"x-xss-protection" = "1; mode=block";
} }}
"401 Unauthorized" indicates that your credentials are incorrect. So check your API keys.
try this:
[twitterClient authorizeUsingOAuthWithRequestTokenPath:#"/oauth/request_token"
userAuthorizationPath:#"/oauth/authorize"
callbackURL:[NSURL URLWithString:#"instantshare-twitter://success"]
accessTokenPath:#"/oauth/access_token"
accessMethod:#"POST"
scope:nil
success:^(AFOAuth1Token *accessToken, id responseObject) {
[twitterClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
} failure:^(NSError *error) {
NSLog(#"Error: %#", error);
}];
Note the line scope:nil, for some reason it doesn't work with empty string.
Among other things, check your application settings in twitter. I'm not sure if this is the case, but I enabled Allow this application to be used to Sign in with Twitter and set Callback URL to some random valid url