First of all, we are using below code so as the api's works only on mobile devices and not on browsers per say.
"
$iPod = stripos($_SERVER['HTTP_USER_AGENT'], "iPod");
$iPhone = stripos($_SERVER['HTTP_USER_AGENT'], "iPhone");
$iPad = stripos($_SERVER['HTTP_USER_AGENT'], "iPad");
$Android = stripos($_SERVER['HTTP_USER_AGENT'], "Android");
$json_data = json_decode(file_get_contents('php://input'));
if ($json_data) {
$username_1 = $json_data->username;
if ($Android || $iPad || $iPhone || $iPod) {}
Secondly, the api's are working on android(using volley) and in ios objective-c using AFNetworking. But, now i am porting the project to swift3 and i am using "Alamofire" for network calls.
Method:: (This is how i make POST request):
let headers : HTTPHeaders = [
"Accept" : "application/json"
]
Alamofire.request("API URL", method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers)
.responseJSON{
response in
if let json = response.result.value{
}
But, i am getting error 404, which we usually get when we hit api in browser.
After that i removed that backend check and the request worked fine and got the proper response. But, we can't remove that check. So help me, if i am making any mistakes with headers of something else.
This is what i am getting in debugPrint(response)::
{ status code: 200, headers {
"Access-Control-Allow-Origin" = "*";
"Cache-Control" = "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
Connection = "Keep-Alive";
"Content-Encoding" = gzip;
"Content-Length" = 84;
"Content-Type" = "text/html; charset=UTF-8";
Date = "Thu, 14 Sep 2017 17:03:17 GMT";
Expires = "Thu, 19 Nov 1981 08:52:00 GMT";
"Keep-Alive" = "timeout=5";
Pragma = "no-cache";
Server = "Apache/2.4.25";
Vary = "Accept-Encoding,User-Agent";
"X-Powered-By" = "PHP/5.6.31";
} }
[Data]: 80 bytes
[Result]: SUCCESS: {
"is_valid" = 0;
status = 404;
"status_message" = "access denied";
success = 0;
}
Alomafire sends a default header parameter User-Agent alright but its value is something like this iOS Example/1.0 (com.alamofire.iOS-Example; build:1; iOS 10.0.0) Alamofire/4.0.0.
This is from their readme:
You can obviously provide your own custom headers:
let headers: HTTPHeaders = [
"User-Agent": "iPhone",
"Accept": "application/json"
]
Alamofire.request("<Ypur URL>", headers: headers)
.responseJSON { response in
debugPrint(response)
}
Or if you want to keep other default header parameters
var headers = Alamofire.SessionManager.defaultHTTPHeaders
headers["User-Agent"] = "iPhone"
Related
I'am using a REST API which returns some JSON block as a response.Here my request fulfills successfully but it returns some header block as a response instead of JSON. What does this code block means ?
P.S : I'm using NSURLSessionDataTask for hitting API.
{
status code: 200, headers {
"Access-Control-Allow-Credentials" = true;
"Access-Control-Allow-Headers" = "origin, content-type, accept, authorization";
"Access-Control-Allow-Methods" = "GET, POST, DELETE, PUT";
"Access-Control-Allow-Origin" = "*";
"Content-Type" = "application/json;charset=utf-8";
Date = "Thu, 08 Sep 2016 08:19:00 GMT";
Server = "Apache-Coyote/1.1";
"Transfer-Encoding" = Id
}
header properties are your servis properties. for example;
Access-Control-Allow-Methods -> Which can call Methods. You can call get, post, delete and put function or services in your services project.
Content-Type -> Services return object type.
I hope that helps.
I am currently building an iOS app which communicates with a ruby-on-rails api. The user management(sign_in, sign_out,...) part of the api is handled with devise_token_auth gem.
I am also using Alamofire to run HTTP requests.
I am currently testing two apis:
POST /api/auth/sign_in(.:format) devise_token_auth/sessions#create
POST /api/posts(.:format) api/posts#create
The first api is used to login while the second creates posts. FYI, in my posts_controller, I am using before_action :authenticate_user! to prevent non authenticated users to create posts.
Here is what I want to do:
Sign in from the client side (iOS app) --> the sign_in api returns the access-token
Create a post from the client side using the access-token.
I managed to get the access-token using this code:
let parameters = [
"email":"omar#omar.com",
"password":"password"]
Alamofire.request(.POST, "http://localhost:3000/api/auth/sign_in", parameters: parameters)
.responseJSON { response in
// get my access token and store it.
}
When I try to create a post(2nd part), here is what I did :
let headers = ["access-token":"<my-token-value>",
"token-type": "Bearer",
"uid":"omar#omar.com"]
let parameters = [
"title":"this is a title",
"body":"this is a body"]
Alamofire.request(.POST, "http://localhost:3000/api/posts", parameters: parameters, headers: headers)
.responseJSON { response in
print(response.response) // URL response
}
When printing the response, here is what I get:
Optional(<NSHTTPURLResponse: 0x7fe422f2b670> { URL: http://localhost:3000/api/posts } { status code: 401, headers {
"Cache-Control" = "no-cache";
Connection = "Keep-Alive";
"Content-Length" = 37;
"Content-Type" = "application/json; charset=utf-8";
Date = "Thu, 03 Mar 2016 15:03:27 GMT";
Server = "WEBrick/1.3.1 (Ruby/2.2.1/2015-02-26)";
"Set-Cookie" = "request_method=POST; path=/";
Vary = Origin;
"X-Content-Type-Options" = nosniff;
"X-Frame-Options" = SAMEORIGIN;
"X-Request-Id" = "82a88799-3fac-42e0-bd01-db5b7e24fcda";
"X-Runtime" = "0.045969";
"X-Xss-Protection" = "1; mode=block";
} })
Also, on Rails server logs:
Filter chain halted as :authenticate_user! rendered or redirected
Completed 401 Unauthorized in 15ms (Views: 0.8ms | ActiveRecord: 4.4ms)
Does anyone know where the error is coming from?
I finally found the solution. Beside expecting the access-token, the token-type and the uid, my API was also expecting the client id in the headers. This client id is sent at the sign_in request response.
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'm using AFNetworking version 3.0 for handling a POST request.
When I run the code I get an error that says:enter code here
2016-01-26 16:48:50.181 Voluntree[3590:1749083] In order to validate a domain name for self signed certificates, you MUST use pinning.
2016-01-26 16:48:50.905 Voluntree[3590:1748745] Error: Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/plain" UserInfo={com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x13deb83d0> { URL: https://voluntree.imrapid.io/signup_by_email } { status code: 200, headers {
"Access-Control-Allow-Headers" = "Origin, X-Requested-With, Content-Type, Accept";
"Access-Control-Allow-Methods" = "POST, GET, OPTIONS, PUT, DELETE, HEAD";
"Access-Control-Allow-Origin" = "*";
Connection = "keep-alive";
"Content-Length" = 4;
"Content-Type" = "text/plain";
Date = "Tue, 26 Jan 2016 14:48:50 GMT";
Server = Cowboy;
Via = "1.1 vegur";
"X-Powered-By" = Express;
} }, NSErrorFailingURLKey=https://voluntree.imrapid.io/signup_by_email, com.alamofire.serialization.response.error.data=<32343634>, NSLocalizedDescription=Request failed: unacceptable content-type: text/plain}
You should change the header "Content-Type" value to application/www-x-form-urlencoded and not "text/plain" as it right now.
For application/x-www-form-urlencoded, the body of the HTTP message sent to the server is essentially one giant query string -- name/value pairs are separated by the ampersand (&), and names are separated from values by the equals symbol (=). An example of this would be:
MyVariableOne=ValueOne&MyVariableTwo=ValueTwo
I haven't changed anything in my app and my code seems to generate the proper URL with access token attached, but I am getting a 400 error bad request for the past day. It doesn't seem as if Instagram has changed the endpoint. Can someone help me decipher the error log to see if there is any usable info here to help me debug? Access Token x'd out.
Failure Error Domain=AFNetworkingErrorDomain Code=-1011 "Request failed: bad request (400)"
UserInfo=0x9261450 {NSErrorFailingURLKey=https://api.instagram.com/v1/locations/search?lat=37.785834&lng=-122.406417&distance=50&access_token=XXXX, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0x92627d0> { URL: https://api.instagram.com/v1/locations/search?lat=37.785834&lng=-122.406417&distance=50&access_token=XXXX }
{ status code: 400, headers {
"Cache-Control" = "private, no-cache, no-store, must-revalidate";
Connection = "keep-alive";
"Content-Language" = en;
"Content-Type" = "application/json; charset=utf-8";
Date = "Tue, 26 Aug 2014 05:19:53 GMT";
Expires = "Sat, 01 Jan 2000 00:00:00 GMT";
Pragma = "no-cache";
Server = nginx;
"Set-Cookie" = "csrftoken=26b1980509fc8303e630689c2d483074; expires=Tue, 25-Aug-2015 05:19:53 GMT; Max-Age=31449600; Path=/, ccode=US; Path=/";
"Transfer-Encoding" = Identity;
Vary = "Cookie, Accept-Language";
"X-Ratelimit-Limit" = 5000;
"X-Ratelimit-Remaining" = 4999;
} }, NSLocalizedDescription=Request failed: bad request (400)}