iOS json: put request with token - objective-c

I have a question concerning json authentication with tokens. I have a server with a database. When I want to POST or PUT to the database I need to have a token with the request, which is unique for every user. I have tried this with a rest client and it works fine. I will attach a print screen of the rest client. But when I want to do it from the app I get the response "Access denied". What am I doing wrong?
Here is my objective-c code:
NSString *jsonRequest = [NSString stringWithFormat:#"{\"name\":\"%#\",\"skills\":\"%#\",\"description\":\"%#\",\"expectation\":\"%#\",\"mail\":\"%#\"}",profileName.text,profileSkills.text,profileDescription.text,profileExpectations.text,profileMail.text];
NSString *testToken = #"6ecf0fe735487bcaab74c0fcd3ed57dc";
NSURL *url = [NSURL URLWithString:#"https://31.208.72.233:3000/persons/63"];
NSData *JSONBody = [jsonRequest dataUsingEncoding:NSUTF8StringEncoding];
NSString *headerValue = [NSString stringWithFormat:#"Authorization: Token %#" , testToken];
NSMutableURLRequest *loginRequest = [[NSMutableURLRequest alloc] initWithURL:url];
loginRequest.HTTPMethod = #"PUT";
loginRequest.HTTPBody = JSONBody;
[loginRequest setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[loginRequest addValue:headerValue forHTTPHeaderField:#"Authorization"];
NSURLResponse *response = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:loginRequest returningResponse:&response error:nil];
NSString *txt = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];

In the headers you have key value pairs. The Authorization is the key part and everything after the : is the value.
It looks like what you may actually be sending is Authorization: Authorization: Token 6ecf0fe735487bcaab74c0fcd3ed57dc. You should remove Authorization from headerValue

Related

NSMutableURLRequest get -1012 http status code instead of 401

I have to pass Authorization token in NSMutableURLRequest , My query is Whenever I have to pass Correct token than I am getting good response with https Status (200.. etc). but whenever I have to pass wrong Authorization token Than I am getting following response insted of http status code 401
* with wrong token response * (I had hide my query htpp:....)
Error Domain=NSURLErrorDomain Code=-1012 "(null)" UserInfo={NSErrorFailingURLStringKey=http......, NSUnderlyingError=0x60800024c420 {Error Domain=kCFErrorDomainCFNetwork Code=-1012 "(null)" UserInfo={_kCFURLErrorAuthFailedResponseKey={url = http.....}}}, NSErrorFailingURLKey=http....}
** here is my code **
// parameter in dictionary
NSDictionary *parameters = #{ #"user_id": [NSNumber numberWithInt:1]};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parameters
options:NSJSONWritingPrettyPrinted
error:&error];
// Convert dictionary to Json String
if (! jsonData) {
NSLog(#"Got an error: %#", error);
} else {
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
jsonparameter = jsonString;
}
NSData *postData = [jsonparameter dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [NSMutableURLRequest
requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:SiteAPIURL,wsname]]];
NSString *Accesstoken = [NSString stringWithFormat:#"Bearer %#",tokenInfo.access_token];
// Set Access token
[request setValue:Accesstoken forHTTPHeaderField:#"Authorization"];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSHTTPURLResponse __autoreleasing *response;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"%#",error.localizedDescription);
NSLog(#"Status code =%ld",(long)response.statusCode);
401 is server generated error. -1012 is system generated error. This sometimes may be because of app is keeping cached certificates and certificate on the server has been changed so they don't match. Clearing Caches and Preferences folders from app's home directory will delete the old certificate data and app will have to download the new one from the server and you problem will be solved.

HTTP "GET" Method Not Returning Any Data in Objective-C

I've already ran a "POST" method to my API, and I successfully retrieved my token, username, and other data.
Now as I run my "GET" method in Xcode, it seems as though I'm not getting any data at all. I ran my Web API through fiddler, and data is being returned, so I know it must be a problem with my code.
Here is the code for my get request (I pass in my token to receive my profile data) :
NSString *get = [NSString stringWithFormat:#"g0pww0uXSrffNtJWWUrguHo-Zwr85EvtbKpAk46oea1Ayl2s7mncoDcXF8f-IJcBrWdxuGFYX3Ua5Tv7ea_IT0HWDB4nyVXrJKrU5f2gpnry4f-qF8zlyaMOQloVIIcqQo0nOY9B87cxvSlAwkZR4hub7CPvXMGpHAJixov2Sb-sE8jEv--cJ1l0Cfr6f3E0nX47-GdalB1XCtIJZgX6ZqpRWxqFaiMKRSZpD5-n087nSfUwQLNAIIA4AG8Hljh1yw3gCHi8fz40ARqkFyOIoXJm6tjtbwZGM44imm4DgP1GeDRqSkM7rVHUeMNmzsmsZWcAxMXDb_P9GbvLwD4_AqsTvuZ00r5UaydPB4m-po4jDf_e3HRKkUOQHAD3jTG_I2TUd6QD3mEyKbK41JsjDDv0LaLvBfTCUskZJKOjXDRanwQJWkselAv5cc5-bEIpvw7HYuFf1lM-O0LSLAXeGYfZS7H-KOdFPJCFUAGO0RH7zdJgatO-sqdx0GNyN_E3"];
NSData *getData = [get dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *getLength = [NSString stringWithFormat:#"%lu", (unsigned long)[getData length]];
NSMutableURLRequest *getRequest = [[NSMutableURLRequest alloc] init];
[getRequest setValue:#"Bearer g0pww0uXSrffNtJWWUrguHo-Zwr85EvtbKpAk46oea1Ayl2s7mncoDcXF8f-IJcBrWdxuGFYX3Ua5Tv7ea_IT0HWDB4nyVXrJKrU5f2gpnry4f-qF8zlyaMOQloVIIcqQo0nOY9B87cxvSlAwkZR4hub7CPvXMGpHAJixov2Sb-sE8jEv--cJ1l0Cfr6f3E0nX47-GdalB1XCtIJZgX6ZqpRWxqFaiMKRSZpD5-n087nSfUwQLNAIIA4AG8Hljh1yw3gCHi8fz40ARqkFyOIoXJm6tjtbwZGM44imm4DgP1GeDRqSkM7rVHUeMNmzsmsZWcAxMXDb_P9GbvLwD4_AqsTvuZ00r5UaydPB4m-po4jDf_e3HRKkUOQHAD3jTG_I2TUd6QD3mEyKbK41JsjDDv0LaLvBfTCUskZJKOjXDRanwQJWkselAv5cc5-bEIpvw7HYuFf1lM-O0LSLAXeGYfZS7H-KOdFPJCFUAGO0RH7zdJgatO-sqdx0GNyN_E3" forHTTPHeaderField:#"Authorization"];
[request setURL:[NSURL URLWithString:#"http://appointmentreminder4.azurewebsites.net/Profile"]];
[getRequest setHTTPMethod:#"GET"];
[getRequest setValue:getLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:getData];
NSURLResponse *getRequestResponse;
NSData *getRequestHandler = [NSURLConnection sendSynchronousRequest:getRequest returningResponse:&getRequestResponse error:nil];
NSString *getRequestReply = [[NSString alloc] initWithBytes:[getRequestHandler bytes] length:[getRequestHandler length] encoding:NSASCIIStringEncoding];
NSLog(#"getRequestReply: %#", getRequestReply);
The output is this:
2014-12-30 11:32:23.384 ARTest[612:303] getRequestReply:
Program ended with exit code: 0
All help is appreciated :)
EDIT:
getRequestHandler returns (null)
getData returns A BUNCH of populated data

.NET Web Api Token Authentication Rest Service "Get" Method in Objective-C

I'm trying to access the following URL:
http://appointmentreminder4.azurewebsites.net/Profile
This URL uses a "Get" method, and is supposed to provide JSON results. Before accessing the URL, you need to login using your Email Address and Password. After logging in successfully, the Web API issues a token. This token is used in ALL communications going forward.
I am currently unable to retrieve the token in Objective-C. I have attempted to google this problem, but I cannot figure out:
1) How to get the token
2) How to get the JSON output from the URL.
Here is the code I have written so far that returns neither the JSON, nor the token:
NSDictionary *postDict = [[NSDictionary alloc] initWithObjectsAndKeys:
#"Email Adress", #"MyEmailAddress",
#"Password", #"MyPassword",
nil];
NSError *error = nil;
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:postDict options:kNilOptions error:&error];
NSURLResponse *response;
NSData *localData = nil;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://appointmentreminder4.azurewebsites.net/home"]];
[request setHTTPMethod:#"POST"];
if (error == nil)
{
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setHTTPBody:jsonData];
// Send the request and get the response
localData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *result = [[NSString alloc] initWithData:localData encoding:NSASCIIStringEncoding];
NSLog(#"Post result : %#", result);
}
If the above link fails, use this link to navigate to the specific page:
http://appointmentreminder4.azurewebsites.net/home

IOS Application to send data to a REST API service content-type definition error

I managed to make an application to send data to a rest api service. The content type must be text/html. But whenever i run my app i get a 415 http code response which means not supported type of content. Here is my code:
NSURL *url = [NSURL new];
NSData *body = nil;
NSString *contentType = #"text/html";
NSURL *finalURL = [NSURL URLWithString:[NSString stringWithFormat:#"http://telesto.zapto.org:81/SMART_EdgeNode/EdgeNode/DataFeeds/3/addMeasurement"]];
NSString *yourString = #"geoX#35#geoY#65";
contentType = #"application/x-www-form-urlencoded; charset=utf-8";
body = [[NSString stringWithFormat:#"%#", yourString] dataUsingEncoding:NSUTF8StringEncoding];
NSString *putLength = [NSString stringWithFormat:#"%d",[body length]];
if (nil==finalURL) {
finalURL = url;
}
NSMutableDictionary* headers = [[[NSMutableDictionary alloc] init] autorelease];
[headers setValue:contentType forKey:#"Content-Type"];
[headers setValue:#"mimeType" forKey:#"Accept"];
[headers setValue:#"no-cache" forKey:#"Cache-Control"];
[headers setValue:#"no-cache" forKey:#"Pragma"];
[headers setValue:#"close" forKey:#"Connection"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:finalURL
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
[request setHTTPMethod:#"PUT"];
[request setAllHTTPHeaderFields:headers];
[request setHTTPBody:body];
[request setValue:putLength forHTTPHeaderField:#"Content-Length"];
self.conn = [NSURLConnection connectionWithRequest:request delegate:self];
I guess atm there is something wrong with defining the content-type . Any help??
Thanks in advance
Ok i found it at last. It was this specific line that was causing the problem and had to do something with the content-type :
contentType = #"application/x-www-form-urlencoded; charset=utf-8";
After removing that i was able to send properly my string to the server.
I think the server's complaining that it doesn't know how to generate a response with the content type "mimeType".
Your Accept header should be "text/html" or whatever the content type you expect in the response, not "mimeType".
Update
After reading this again, I notice that you are setting the contentType to #"text/html", then to #"application/x-www-form-urlencoded; charset=utf-8". Which do you need? From the description, you want to sent text/html, but that is not what your sending. When you set contentType to #"application/x-www-form-urlencoded; charset=utf-8", text/html is lost.

NSURLConnection closes early on GET

I'm working on a method to centralize my URL connections for sending and receiving JSON data from a server. It works with POST, but not GET. I'm using a Google App Engine server and on my computer it'll handle the POST requests and return proper results (and log appropriately), but I get the following error when I try the request with a GET method:
Error Domain=kCFErrorDomainCFNetwork Code=303 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error 303.)" UserInfo=0xd57e400 {NSErrorFailingURLKey=http://localhost:8080/api/login, NSErrorFailingURLStringKey=http://localhost:8080/api/login}
In addition, the GAE dev server shows a "broken pipe" error, indicating that the client closed the connection before the server was finished sending all data.
Here's the method:
/* Connects to a given URL and sends JSON data via HTTP request and returns the result of the request as a dict */
- (id) sendRequestToModule:(NSString*) module ofType:(NSString*) type function:(NSString*) func params:(NSDictionary*) params {
NSString *str_params = [NSDictionary dictionaryWithObjectsAndKeys:func, #"function", params, #"params", nil];
NSString *str_url = [NSString stringWithFormat:#"%#%#", lds_url, module];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:str_url]];
NSData *data = [[NSString stringWithFormat:#"action=%#", [str_params JSONString]] dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPMethod:type];
[request setHTTPBody:data];
[request setValue:[NSString stringWithFormat:#"%d", [data length]] forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
NSError *error = nil;
NSURLResponse *response = nil;
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"Error: %#", error);
NSLog(#"Result: %#", [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding]);
return [result objectFromJSONData];
}
A sample call would be:
NSDictionary *response = [fetcher sendRequestToModule:#"login" ofType:#"GET" function:#"validate_email" params:dict];
Again, this works with a POST but not a GET. How can I fix this?
In my case i was not calling [request setHTTPMethod: #"POST" ]
I think the root cause is you have an invalid URL.
JSON encoding will include things like '{', '}', '[' and ']'. All of these need to be URL encoded before being added to a URL.
NSString *query = [NSString stringWithFormat:#"?action=%#", [str_params JSONString]];
query = [query stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:#"%#%#", str_url, query]];
To directly answer your question:
According to CFNetwork Error Codes Reference the error is kCFErrorHTTPParseFailure. This means the client failed to correctly parse the HTTP response.
The reason why is that a GET doesn't include a body. Why would you want to submit JSON in a GET anyways?
If the target api returns data only you pass it in the url params.
If you want to send data and "get" a response use a post and examine the body on return.
Sample Post:
NSError *error;
NSString *urlString = [[NSString alloc] initWithFormat:#"http://%#:%#/XXXX/MVC Controller Method/%#",self.ServerName, self.Port, sessionId ];
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding ]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
// hydrate the remote object
NSString *returnString = [rdc JSONRepresentation];
NSData *s10 = [returnString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:s10];
NSURLResponse *theResponse = [[NSURLResponse alloc] init];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&theResponse error:&error];
NSString *message = [[NSString alloc] initWithFormat: #"nothing"];
if (error) {
message = [[NSString alloc] initWithFormat:#"Error: %#", error];
} else {
message = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
NSLog(#"%#", message);
return message;