Authentication problems in obj-c


(Alex Okita) #1

So I'm trying to get objective-c to authenticate with the following code

-(void) didFinishSavingMeshForUploadToSketchfab:(NSDictionary*)attachmentsInfo
                                      withToken:(NSString*)token
                                    andPassword:(NSString*)password
{
    //Get the zip file
    NSString* zipFilePath = attachmentsInfo[@"zipTemporaryFilePath"];
    NSString* zipFilename = attachmentsInfo[@"zipFilename"];
    NSData *zipData = [NSData dataWithContentsOfFile:zipFilePath];

    //url to sketchfab api
    NSURL *sketchFabURL = [NSURL URLWithString:@"https://api.sketchfab.com/v2/models"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:sketchFabURL];
    [request setHTTPMethod:@"POST"];
    [request addValue:@"application/octet-stream" forHTTPHeaderField:@"content-type"];

    [request addValue:token forHTTPHeaderField:@"token"];
    [request addValue:password forHTTPHeaderField:@"password"];

    [request addValue:zipFilename forHTTPHeaderField:@"title"];

    NSString *encodedZip = [[NSString alloc] initWithData:zipData encoding:NSUTF8StringEncoding];
    [request addValue:encodedZip forHTTPHeaderField:@"fileModel"];

    [request setTimeoutInterval:10.0];
    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    NSLog(@"connecting...");
}

This is returns:

"detail":"Authentication credentials were not provided."

in the connection didReceiveData: delegate. Not sure why either the token or password aren't being encoded and sent properly, or if i'm simply missing something. I'm trying to get this working with out the AFHTTPRequestOperation and AFHTTPRequestOperationManager libs for various reasons.

Also tried

    NSData *tokenData = [[NSData alloc] initWithBase64EncodedString:token options:NSDataBase64EncodingEndLineWithLineFeed];
NSString *tokenString = [[NSString alloc] initWithData:tokenData encoding:NSISOLatin2StringEncoding];
[request addValue:tokenString forHTTPHeaderField:@"token"];

and other various encodings for the token field

Perhaps i'm missing something simple here? Any help would be greatly appreciated

thanks!
a.o


(Alex Okita) #2

Ah okay, so i got to:

[request addValue:[NSString stringWithFormat:@"Token token=\"%@\"", tokenString] forHTTPHeaderField:@"Authorization"];

This now gives me the response:

{"detail":"Invalid token"}

So then I tried:

NSString *tokenString = [[NSString alloc] initWithData:tokenData encoding:NSUTF8StringEncoding];
[request addValue:[NSString stringWithFormat:@"Token token=\"%@\"", tokenString] forHTTPHeaderField:@"Authorization"];

but I'm still getting an invalid token, so I'm thinking it's something to do with the string encoding. Perhaps a different encoding??

anyone have any suggestions?


#3

I am lost in obj-c... maybe @pap can help?


(Pierre-Antoine) #4

Hi @alex_okita,

From reading the code, I think it has nothing to do with the string encoding.
The issue is that you're setting values as "httpHeaderField", instead of the body of the POST request, which is why it fails to process the request. (note: you can authenticate using a token in the headers, but only with an oauth2 token, and that's a whole different story smile )

From what I remember, the default objective-c networking library is very poor, and you'll have a hard time adding parameters in the body, let alone attaching your model file.

I highly suggest adding the AFNetworking library to your project and using it, it will save you a lot of time and be much simpler to user : https://github.com/AFNetworking/AFNetworking

Let us know how it goes !

PA


(Alex Okita) #5

So thus far I've been able to assign the token and get a response which looks like it's accepted the auth token. In case anyone would like to see how that works this is the obj-c i've managed to get working.

NSURL *sketchFabURL = [NSURL URLWithString:@"https://api.sketchfab.com/v2/models"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:sketchFabURL];
[request setHTTPMethod:@"POST"];
NSString *boundary = @"-----";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
[request addValue:contentType forHTTPHeaderField:@"Content-Type"];

//create body data
NSMutableData *body = [NSMutableData data];

//assign token for body
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"token\"\r\n\r\n%@", token] dataUsingEncoding:NSUTF8StringEncoding]];

now that the token was accepted I'm working on the data stream for the zip file.

For various reasons we're avoiding adding any external libs to our apps, so i'm trying to do as much as i can without the AFNetworking lib, i did download it and it's rather cool, i might use it for some personal projects, but I'm trying to avoid using it for the current project.

that being said, what encoding is the zip upload expected in? just hoping to avoid some random testing for the next couple of hours.


(Alex Okita) #6

Looks like i managed to get it working without any external libs. so. it's not pretty and im not actually sure why this all works, but...

-(void) didFinishSavingMeshForUploadToSketchfab:(NSDictionary*)attachmentsInfo withToken:(NSString*)token
{
    //this creates the request to a URL
    NSURL *sketchFabURL = [NSURL URLWithString:@"https://api.sketchfab.com/v2/models"];
    NSString* zipFilePath = attachmentsInfo[@"zipTemporaryFilePath"];
    NSString* zipFilename = attachmentsInfo[@"zipFilename"];

    //Get the zip file
    NSError *error;
    NSData *zipData = [NSData dataWithContentsOfFile:zipFilePath options:NSUTF8StringEncoding error:&error];
    if(error)
    {
        NSLog(@"error: %@", error);
    }

    NSLog(@"sketchFabURL: %@", sketchFabURL );
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:sketchFabURL];
    //set to post method
    [request setHTTPMethod:@"POST"];
    NSString *boundary = @"-----BNDRY";
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    [request addValue:contentType forHTTPHeaderField:@"Content-Type"];

    //create body data
    NSMutableData *body = [NSMutableData data];

    //assign token for body
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"token\"\r\n\r\n%@", token] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

    //give the file a name
    NSString *modelFileString = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"modelFileName\"\r\n\r\n%@", zipFilename];
    [body appendData:[modelFileString dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"modelFile\"; filename=\"%@.jpg\"\r\n", zipFilename] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[NSData dataWithData:zipData]];
    [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

    //attach body Data to request
    [request setHTTPBody:body];

    [request setTimeoutInterval:10.0];
    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    NSLog(@"connecting...");
}

I have a delegate that returns a NSURLCredential with the user:token and password:"" which seems to be fine. In any case I was able to post a file from the app. hope this might be useful to someone else who might not want to use the AFNetworking lib.

cheers!


(Pierre-Antoine) #7

@alex_okita great job thanks for sharing!