3

I am working with GitHub's REST API for iOS and am having trouble getting it to work correctly with basic authentication. I have written the following code to view a users GitHub repositories:

    NSString *requestString = [NSString stringWithFormat:@"https://%@:%@@api.github.com/user/repos",userName,password];
    NSURL *url = [NSURL URLWithString:requestString];
    NSURLRequest *req = [NSURLRequest requestWithURL:url];

    NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
        NSString *strData = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"%@", strData);
    }];

    [dataTask resume];

I am getting the following response back:

{"message":"Requires authentication","documentation_url":"https://developer.github.com/v3"}

However when I do the following in my terminal:

curl -i GET  https://userName:password@api.github.com/user/repos

I get the expected result back from GitHub. I'm not sure what authentication I am missing for my iOS app because I don't have anything in my curl statement that I don't have in my iOS code. Any help explaining what I'm missing is greatly appreciated.

user2604504
  • 697
  • 2
  • 14
  • 29

2 Answers2

5

It seems that something in NSURLSession doesn't like the username/password encoded in the URL (and to be honest, it isn't very secure as it can be exposed in proxy logs and is also prone to problems on the server side), so you have to encode the authorisation details into the HTTP headers.

This worked for me -

NSString *requestString = @"https://api.github.com/user/repos";
NSURL *url = [NSURL URLWithString:requestString];
NSURLRequest *req = [NSURLRequest requestWithURL:url];

NSData *userPasswordData = [[NSString stringWithFormat:@"%@:%@", userName, password] dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64EncodedCredential = [userPasswordData base64EncodedStringWithOptions:0];
NSString *authString = [NSString stringWithFormat:@"Basic %@", base64EncodedCredential];

NSURLSessionConfiguration *sessionConfig=[NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfig.HTTPAdditionalHeaders=@{@"Authorization":authString};

self.session=[NSURLSession sessionWithConfiguration:sessionConfig];

NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
    NSString *strData = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"%@", strData);
}];

[dataTask resume];
Paulw11
  • 108,386
  • 14
  • 159
  • 186
  • Hi @Paulw11 ! Is there a way to modify your code to get the token from github? I'm stuck on a task I have. If you have time, take a look at my questions regarding github api. I would be very grateful. – Amer Hukic May 11 '15 at 13:17
0

I can see two possible reasons:

  1. your password contains special characters that needs to be "percent escaped": see "NSString method to percent escape '&' for URL"

  2. the @@ is somehow misinterpreted: you can try to POST the username and password as in this question

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250