RestKit Login problem - ios

Can anyone give me a hint why I can not login into my service? I dont get an response to my delegate. The service is working. If I call the url in my browser I get a login (Browser receives a cookie) and then I can call request on my service:
Here is my Code:
RKClient *client =[RKClient clientWithBaseURL:#"https://myserverinstance/mobileapp/"];
NSString *loginString = #"SSO.login?application=myAppName&language=en&username=MyUserName&password=MyPassword&permanentLogin=true";
[RKClient setSharedClient:client];
if([[RKClient sharedClient] isNetworkAvailable]){;
NSLog(#"Network is available");
[[RKClient sharedClient] get:loginString delegate:self];

I'm assuming that the typos in your posted code (e.g. if([[RKClient sharedClient] isNetworkAvailable]){;) do not exist in your actual project.
Are your SSL certificates self-signed? If so, you'll need to set the RESTKIT_SSL_VALIDATION preprocessor directive. You'll also need to link against Security.framework.
If your certificates are signed by a common authority, then you should post more information about your problem. Turn RestKit logging on with RKLogConfigureByName("RestKit/Network", RKLogLevelTrace); and see if that provides any hints to where the problem really lies.

Related

AFNetworking 2.0 - unexpected NSURLErrorDomain error -1012

We ran into the following issue with our app that uses AFNetworking 2.0.
When using AFHTTPRequestOperationManager's GET method, we got an error NSURLErrorDomain code -1012. The request used HTTPS and the server does not require user authentication. The request never reached the server by the way.
We have run several tests and this is the first time the error was produced and we are wondering how this error can get produced because it does not seem relevant.
Setup of AFHTTPRequestOperationManager :
httpOperationManager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:
[NSURL URLWithString: HTTPS_URL)]];
httpOperationManager.responseSerializer =
[AFXMLParserResponseSerializer serializer];
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled: YES];
GET REQUEST
AFHTTPRequestOperation *op =[httpOperationManager GET:
[NSString stringWithFormat:SOME_PATH]
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
//code to setup NSXMLParser ...
}
failure: ^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error %#", [error localizedDescription]);
}];
I think you already solved the problem, but if you are trying to authenticate in a server that doesn't have a valid certificate you have to set YES for property allowInvalidCertificates in your AFHTTPRequestOperationManager object:
[yourManager.requestSerializer setAuthorizationHeaderFieldWithUsername:#"your_username" password:#"your_password"];
[yourManager.securityPolicy setAllowInvalidCertificates:YES];
Also, as #a1phanumeric said, it can be necessary to include this line:
[yourManager.securityPolicy setValidatesDomainName:NO];
Cheers.
NSURLErrorDomain -1012 is NSURLErrorUserCancelledAuthentication. (See the error code list and search for -1012.)
You state, "the server does not require user authentication". But this error would not be called if that were true.
Possible causes:
Your server is erroneously requesting authorization (a server bug)
The URL formed with HTTPS_URL and SOME_PATH is not what you expect, and some other server is requesting authorization
Some intermediary (like a proxy server, or an access point) is requiring authorization.
Some debugging tips:
Set breakpoints inside the AFNetworking implementation to see which URL is being hit
Configure AFHTTPRequestOperationLogger so you can see the actual request body and response in your console log
Make the same request with curl or Advanced Rest Client and observe the server's response
Side note: I think [NSString stringWithFormat:SOME_PATH] is pointless - why not just use SOME_PATH?

Login form with AFNetworking 1.3

I am trying to login into a website through an HTML form using AFNetworking 1.3. I simply set my credentials and POST to the proper path. The problem is that I am not issued a cookie that states that I am logged in.
NSURL *baseURL = [NSURL URLWithString:#"https://mysite.edu"];
AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:baseURL];
NSString *loginPath = #"/place/loginPage";
NSDictionary *loginParameters = #{#"sid" : #"username",
#"PIN" : #"12345678"};
NSMutableURLRequest *request = [client multipartFormRequestWithMethod:#"POST"
path:loginPath
parameters:loginParameters
constructingBodyWithBlock:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"success: %#", operation.responseString);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", operation.responseString);
}];
[operation start];
The web server is returning a webpage that states that I do not have cookies enabled:
This system requires the use of HTTP cookies to verify authorization information.
Our system has detected that your browser has disabled HTTP cookies, or does not support them.
Please refer to the Help page in your browser for more information on how to correctly configure your browser for use with this system.
However, if I iterate through my issued cookies, I find that the website has issued me cookies, but not a session cookie. Therefore my AFNetworking client really is accepting cookies? Is there a setting that I must adjust to allow session cookies to properly work with AFNetworking 1.3?
I have edited my HTTP request header to match working browsers such as Chrome.
[Is] my AFNetworking client really [] accepting cookies? Is there a setting that I must adjust to allow session cookies to properly work with AFNetworking 1.3?
AFNetworking has no cookie-specific configuration. Cookies are solely the responsibility of the Foundation URL Loading system.
Some possible solutions:
Install AFHTTPRequestOperationLogger and configure it with AFLoggerLevelDebug to see all HTTP headers. This will let you see what's actually getting sent and received in your Xcode console.
The server may be dropping the cookie, for example if it's a Ruby server with protect_from_forgery enabled. Check your server logs and this solution for information on disabling or sending the appropriate token.
You control how requests use cookies with -[NSMutableURLRequest setHTTPShouldHandleCookies]. Make sure this is set to YES (the default.)
Other apps can alter the Cookie Accept Policy, so make sure -[NSHTTPCookieStorage cookieAcceptPolicy] is returning NSHTTPCookieAcceptPolicyAlways (or NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain if you need it.)
Since I came here while searching for a working solution for AFNetworking 2.0, not knowing that AFHTTPClient was removed from the Framework, I will post the new way to establish this connection here:
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:#"http://examplewebsite.com"]];
[manager setRequestSerializer:[AFHTTPRequestSerializer serializer]];
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:#"userName" password:#"password"];

Migrate restkit v0.20

Migrated to v0.20 and looks like RKClient deprecated.
Any idea how to set the user name and password? I used to do this in 1.0
[[RKClient sharedClient] setUsername:#"username"];
[[RKClient sharedClient] setPassword:#"password"];
Instead of the RKClient RestKit 0.20 now uses AFNetworking and it's client methods. However you can call the client of the RKObjectManager via HTTPClient, so setting the authorization header should be looking like
[[RKObjectManager sharedManager].HTTPClient setAuthorizationHeaderWithUsername:#"username"
password:#"password"];
For all other methods (authorization isn't listed there), check out the wiki document.

User Login With AFNetworking

I am building my first iOS app.
I have got the backend code done, but I am struggling with the Objective-C part of it.
I have a signup / login page.
But I don't know how to send that data to my server using Objective C.
I have read that AFNetworking is good, but I was wondering how I could use that for user login .
I have downloaded and added AFNetworking to my XCode Project and set up headers.
AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:#"http://examplewebsite.com]];
[client setDefaultHeader:#"key" value:#"value"];
[client setAuthorizationHeaderWithUsername:#"username" password:#"password"];
[client setAuthorizationHeaderWithToken:#"token"];
NSURLRequest *request = [client requestWithMethod:#"someMethod" path:#"somePath" parameters:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
but I am still lost.
Since you're trying to login to your own API, you don't want setAuthorization stuff. That's for basic HTTP auth. Instead you want to use getPath:parameters:success:failure or the postPath version, depending on if your backend is expecting HTTP GET or HTTP POST.
Pass your userid / password in the parameters argument. You should set parameterEncoding to be the correct format. You're probably using HTTP Forms url encoding, or JSON. Whatever your backend expects.
You don't want to set the authorization headers in this case, since this is for "basic access HTTP authentication", which is a method for a HTTP user agent to provide a user name and password when making a request to a server.
You want to use your own API and interact with a restful server and therefore, I would recommend, that you subclass AFHTTPClient -> interact with an API, Web Service, or Application. - Take a look at the examples in the AFNetworking zip archive, if you have difficulties in subclassing AFHTTPClient.
Since you want to create an app with user login, the app needs to send these information to your server, and the server should return if the login was succesful or not.
This can be done like so - HTTP POST.
- (void)login {
// Login information from UITextFields
id params = #{
#"username": self.usernameField.text,
#"password": self.passwordField.text
};
//Call the AFHTTP subclass client, with post block. postPath = the path of the url, where the parameters should be posted.
[[theAuthAPIClient sharedClient] postPath:#"/login"
parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject) {
//handle succesful response from server.
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// handle error - login failed
}
}];
}
You need to pass the parameters in the right format, depending on what format your server expects. This can be done by setting the right encoding in your AFHTTPClient subclass -> ParameterEncoding
Since I came here while searching for a working solution for AFNetworking 2.0, not knowing that AFHTTPClient was removed from the Framework, I will post the new way to establish this connection here:
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:#"http://examplewebsite.com"]];
[manager setRequestSerializer:[AFHTTPRequestSerializer serializer]];
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:#"userName" password:#"password"];

ios - Restkit and SSL certificate error

I have a tomcat server that uses a self signed SSL certificate and is running a web service. I am trying to connect to the web service with Restkit. However, I am getting an error related to certificate validity. Here is my code:
NSURL *url=[NSURL URLWithString:baseURL];
RKClient *client = [RKClient clientWithBaseURL:url];
client.disableCertificateValidation=YES;
RKRequest *request = [client requestWithResourcePath:[NSString stringWithFormat:#"/addEvent?deviceID=%#&eventID=%#",deviceID,eventID]];
request.disableCertificateValidation=YES;
request.delegate=self;
RKResponse *response = [request sendSynchronously];
This request fails with the following error:
2013-01-09 15:11:53.931 Mobile_ACPL[5761:907] The certificate for this server is invalid. You might be connecting to a server that is pretending to be “notify.acpl.lib.in.us” which could put your confidential information at risk.
I get this error even though I have set disableCertificateValidation to YES. How can I get this working?
EDIT: I attempted adding the certificate as shown here: https://github.com/RestKit/RestKit/pull/131
I still get the same result.
EDIT 2: It looks like the error message is being set at this line in RKRequest.m:
payload = [NSURLConnection sendSynchronousRequest:_URLRequest returningResponse:&URLResponse error:&error];
NSURLConnection does not cater for authentication challenges in synchronous calls. You need to make asynchronous calls for this to work.
In my case, I was setting disableCertificateValidation on RKClient but I was using a RKObjectManager which used a different RKClient. The following line, placed after the RKObjectManager initialization, did the trick:
[RKObjectManager sharedManager].client.disableCertificateValidation = YES;
if you are using RestKit using
client.allowsInvalidSSLCertificate = YES;
won't work, instead do this:
if you added rest kit manually to your project, click on RestKit.xcodeproj go to project > Build Settings > Preprocessor Macros
and add _AFNETWORKING_ALLOW_INVALID_SSL_CERTIFICATES_=1
thats finished.

Resources