Question

Basically, I'm trying to login to this website called Mistar. I can do it using php:

<form action="https://mistar.oakland.k12.mi.us/novi/StudentPortal/Home/Login" method="post">
<input type=text name="Pin">
<input type=password name="Password">
<input type="submit" id="LoginButton">
</form>

So the php (when you run it) works. You use a Pin (20005012) and a Password (wildcats) it authenticates and returns a page with something like {1, User Authenticated}

Now what I'm trying to do is login to the website from an iPhone app (so ObjC), probably using NSURLSession or something.

This is what I have so far, but it keeps giving me an error to the login page:

- (void)loginToMistar {

    //Create POST request
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];

    //Create and send request
    NSURL *url = [NSURL URLWithString:@"https://mistar.oakland.k12.mi.us/novi/StudentPortal/Home/Login"];
    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
    NSString *postString = [NSString stringWithFormat:@"<input type=text name='Pin'> <input type=password name='Password'> <input type='submit' id='LoginButton'>"];
    NSData * postBody = [postString dataUsingEncoding:NSUTF8StringEncoding];
    [request setHTTPBody:postBody];

 //   [request addValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    NSString* url=[NSString stringWithFormat:url];

    [NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
    {
        // do whatever with the data...and errors
        if ([data length] > 0 && error == nil) {
            NSString *loggedInPage = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(loggedInPage);
        }
        else {
            NSLog(@"error");
        }
    }];

Could someone tell me where the problem in my code is?

Was it helpful?

Solution

  1. Generally, you'd want to specify the Content-type of request (application/x-www-form-urlencoded).

  2. You want to build the body of the request to conform to that type of request (as cmorrissey said), e.g. Pin=xxx&Password=yyy.

  3. You want to make sure you percent-escape those values, xxx and yyy (because, if the password contained any reserved characters like +, the password would not be transmitted correctly).

  4. You need to specify that your request is a POST request. So, use that original NSMutableURLRequest and configure it properly and retire your NSURLRequest.

  5. You don't want that line that says:

    NSString* url=[NSString stringWithFormat:url];
    
  6. You don't have to create an operation queue. You can, but (a) you're not doing something really slow and computationally expensive; and (b) it's likely that this completion block may eventually want to update the UI, and you never do that on a background queue, but only the main queue.

  7. Since the response appears to be JSON, let's go ahead and parse that response (if we can).

Thus, you end up with something like:

- (void)loginToMistarWithPin:(NSString *)pin password:(NSString *)password {

    NSURL *url = [NSURL URLWithString:@"https://mistar.oakland.k12.mi.us/novi/StudentPortal/Home/Login"];

    //Create and send request
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];

    [request setHTTPMethod:@"POST"];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-type"];

    NSString *postString = [NSString stringWithFormat:@"Pin=%@&Password=%@",
                            [self percentEscapeString:pin],
                            [self percentEscapeString:password]];
    NSData * postBody = [postString dataUsingEncoding:NSUTF8StringEncoding];
    [request setHTTPBody:postBody];

    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
     {
         // do whatever with the data...and errors
         if ([data length] > 0 && error == nil) {
             NSError *parseError;
             NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
             if (responseJSON) {
                 // the response was JSON and we successfully decoded it

                 NSLog(@"Response was = %@", responseJSON);
             } else {
                 // the response was not JSON, so let's see what it was so we can diagnose the issue

                 NSString *loggedInPage = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                 NSLog(@"Response was not JSON, it was = %@", loggedInPage);
             }
         }
         else {
             NSLog(@"error: %@", error);
         }
     }];
}

- (NSString *)percentEscapeString:(NSString *)string
{
    NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                                                 (CFStringRef)string,
                                                                                 (CFStringRef)@" ",
                                                                                 (CFStringRef)@":/?@!$&'()*+,;=",
                                                                                 kCFStringEncodingUTF8));
    return [result stringByReplacingOccurrencesOfString:@" " withString:@"+"];
}

You could then call this like so:

[self loginToMistarWithPin:@"20005012" password:@"wildcats"];

OTHER TIPS

The following line is incorrect.

NSString *postString = [NSString stringWithFormat:@"<input type=text name='Pin'> <input type=password name='Password'> <input type='submit' id='LoginButton'>"];

as "<input type=text name='Pin'> <input type=password name='Password'> <input type='submit' id='LoginButton'>" is not a proper POST string

You need to replace that with something like "Pin=20005012&Password=wildcats"

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top