objective-c - 带有用于 Objective-C 的 ClientLogin 接口(interface)的 Google App Engine

标签 objective-c cocoa cocoa-touch google-app-engine

我在 this previous stackoverflow.com post 遇到了同样的问题.

具体来说,我似乎能够正确获取“Auth” token ,但是当我访问后面的页面时尝试在 header 中使用它仍然只是返回登录页面的 HTML。

通过与本文相关的链接,我确定您需要随后调用 this URL .

然后,对该 URL 的调用将为您提供一个 ACSID cookie,然后需要在后续调用中传递该 cookie 以保持经过身份验证的状态。

当请求这个 cookie 时,我读过各种帖子说你需要通过将它附加到查询字符串来指定你的原始身份验证 token ,这样:

?auth=this_is_my_token

我还读到您应该按照 google's documentation 中的描述在 http header 中设置它这样一个 http header 名称/值是:

Authorization: GoogleLogin auth=yourAuthToken

我已经尝试了这两种方法,但没有看到返回任何 cookie。我已经使用 Wireshark、Firefox 的 LiveHttpHeaders 和简单的 NSLog 语句来尝试查看是否返回了类似的内容。

下面是我一直在使用的代码片段。

NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"http://yourapp.appspot.com/_ah/login?auth=%@", [token objectForKey:@"Auth"]]];
NSHTTPURLResponse* response;
NSError* error;
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setValue:[NSString stringWithFormat:@"GoogleLogin auth=%@", [token objectForKey:@"Auth"]] forHTTPHeaderField:@"Authorization"];
NSData * data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];  

//show me all header fields
NSLog([[response allHeaderFields] description]);

//show me the response
NSLog(@"%@", [[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] autorelease]);
NSArray * all = [NSHTTPCookie cookiesWithResponseHeaderFields:[response allHeaderFields] forURL:[NSURL URLWithString:@"http://yourapp.appspot.com/_ah/login"]];

//show me all cookies
for (NSHTTPCookie *cookie in all) 
{
    NSLog(@"Name: %@ : Value: %@", cookie.name, cookie.value); 
}

我希望您可以使用 ClientLogin 获取 Google App Engine 代码。

最佳答案

将示例代码添加到此问题是因为有人就我的解决方案直接与我联系。请注意,您必须在初始 token 请求中将“service”参数设置为“ah”。

token 的初始请求 [同步完成] 注意:“服务”参数设置为“啊”,“源”仅设置为“myapp”,您应该使用您的应用程序名称。

//create request
NSString* content = [NSString stringWithFormat:@"accountType=HOSTED_OR_GOOGLE&Email=%@&Passwd=%@&service=ah&source=myapp", [loginView username].text, [loginView password].text];
NSURL* authUrl = [NSURL URLWithString:@"https://www.google.com/accounts/ClientLogin"];
NSMutableURLRequest* authRequest = [[NSMutableURLRequest alloc] initWithURL:authUrl];
[authRequest setHTTPMethod:@"POST"];
[authRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-type"];
[authRequest setHTTPBody:[content dataUsingEncoding:NSASCIIStringEncoding]];

NSHTTPURLResponse* authResponse;
NSError* authError;
NSData * authData = [NSURLConnection sendSynchronousRequest:authRequest returningResponse:&authResponse error:&authError];  

NSString *authResponseBody = [[NSString alloc] initWithData:authData encoding:NSASCIIStringEncoding];

//loop through response body which is key=value pairs, seperated by \n. The code below is not optimal and certainly error prone. 
NSArray *lines = [authResponseBody componentsSeparatedByString:@"\n"];
NSMutableDictionary* token = [NSMutableDictionary dictionary];
for (NSString* s in lines) {
    NSArray* kvpair = [s componentsSeparatedByString:@"="];
    if ([kvpair count]>1)
        [token setObject:[kvpair objectAtIndex:1] forKey:[kvpair objectAtIndex:0]];
}

//if google returned an error in the body [google returns Error=Bad Authentication in the body. which is weird, not sure if they use status codes]
if ([token objectForKey:@"Error"]) {
    //handle error
};

下一步是让您的应用程序在 google app engine 上运行,以便为您提供 ASCID cookie。我不确定为什么会有这个额外的步骤,这似乎是谷歌端的一个问题,可能是为什么 GAE 目前不在他们列出的 obj-c 谷歌数据 api 库中。我的测试显示我请求 cookie 以便与 GAE 同步。另外,请注意我没有对 cookie 做任何事情。似乎只是通过请求它并获取 cookie, future 的请求将自动包含 cookie。我不确定这是否是 iphone 的东西,因为我的应用程序是 iphone 应用程序,但我不完全理解这个 cookie 发生了什么。注意:使用“myapp.appspot.com”。

NSURL* cookieUrl = [NSURL URLWithString:[NSString stringWithFormat:@"http://myapp.appspot.com/_ah/login?continue=http://myapp.appspot.com/&auth=%@", [token objectForKey:@"Auth"]]];
    NSLog([cookieUrl description]);
    NSHTTPURLResponse* cookieResponse;
    NSError* cookieError;
    NSMutableURLRequest *cookieRequest = [[NSMutableURLRequest alloc] initWithURL:cookieUrl];

    [cookieRequest setHTTPMethod:@"GET"];

    NSData* cookieData = [NSURLConnection sendSynchronousRequest:cookieRequest returningResponse:&cookieResponse error:&cookieError];   

最后,我可以将 json 发布到我的 gae 应用程序。注意:下面的片段是一个异步请求。我们可以通过实现 didReceiveResponse、didReceiveData、didFailWIthError 来处理响应。

NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"http://myapp.appspot.com/addRun?auth=%@", mytoken]];
    NSMutableURLRequest* request = [[NSMutableURLRequest alloc] initWithURL:url];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:@"my http body";

    NSURLConnection *connectionResponse = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    if (!connectionResponse) {
        NSLog(@"Failed to submit request");
    } else {
        NSLog(@"Request submitted");
    }

关于objective-c - 带有用于 Objective-C 的 ClientLogin 接口(interface)的 Google App Engine,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/471898/

相关文章:

objective-c - Cocoa中如何按扇区读取文件而不依赖操作系统缓存

ios - 尝试访问 long double Math 宏和 long double 的精度

objective-c - 使用多个 nsarraycontroller 更改选定对象

ios - 检查当前响应者?

objective-c - 将 NSString 拆分为 Objective-C 中的数组

iphone - 我是否想对 UI 变量使用除 "retain"和 "nonatomic"之外的任何 @property 属性?

ios - 在 NSArray 中改变 NSDictionary

ios - 为什么我不能从另一个类中获取关联的对象?

ios - 更改按钮标签字体颜色和标题

objective-c - NSTableView 选择 & 亮点