带有用于 Objective-C 的 ClientLogin 接口的 Google App Engine [英] Google App Engine with ClientLogin Interface for Objective-C

查看:19
本文介绍了带有用于 Objective-C 的 ClientLogin 接口的 Google App Engine的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 之前的 stackoverflow.com 帖子.

具体来说,我似乎能够正确获取Auth"令牌,但是当我访问以后的页面时尝试在标题中使用它仍然只会返回登录页面的 HTML.

Specifically, I seem to be able to get the "Auth" token correctly, but attempts to use it in the header when I access later pages still just return me the login page's HTML.

按照与此帖子相关的链接,我确定您需要随后调用 this网址.

Following links related to this post, I've determined that you need to make a subsequent call to this URL.

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

A call to the URL will then give you an ACSID cookie which then needs to be passed in subsequent calls in order to maintain an authenticated state.

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

When requesting this cookie, I've read various posts saying you need to specify your original auth token by appending it to the query string such that:

?auth=this_is_my_token

我还了解到您应该按照 google 的文档 使得 http 标头名称/值是:

I've also read that you should set it in the http header as described in google's documentation such that a http header name/value is:

Authorization: GoogleLogin auth=yourAuthToken

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

I've tried both approaches and am not seeing any cookies returned. I've used Wireshark, LiveHttpHeaders for Firefox, and simple NSLog statements trying to see if anything like this is returned.

以下是我一直在使用的代码片段.

Below is the code snippet I've been using.

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 代码.

I hope you can use ClientLogin for Google App Engine code.

推荐答案

向这个问题添加示例代码,因为有人直接联系我讨论我的解决方案.请注意,您必须在初始令牌请求中将service"参数设置为等于ah".

Adding sample code to this question because someone contacted me directly about my solution. Note that you must set the "service" parameter equal to "ah" on the initial token request.

令牌的初始请求[同步完成] 注意:service"参数设置为ah",source"设置为myapp",您应该使用您的应用程序名称.

Initial Request of Token [done synchronously] NOTE: the "service" parameter is set to "ah" and the "source" is just set to "myapp", you should use your app name.

//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 
. The code below is not optimal and certainly error prone. 
NSArray *lines = [authResponseBody componentsSeparatedByString:@"
"];
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
};

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

The next step is to get your app running on google app engine to give you the ASCID cookie. I'm not sure why there is this extra step, it seems to be an issue on google's end and probably why GAE is not currently in their listed obj-c google data api library. My tests show I have to request the cookie in order sync with GAE. Also, notice I don't do anything with the cookie. It seems just by requesting it and getting cookied, future requests will automatically contain the cookie. I'm not sure if this is an iphone thing bc my app is an iphone app but I don't fully understand what is happening with this cookie. NOTE: the use of "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 来处理响应.

Finally, I can post json to my gae app. NOTE: the snippet below is an async request. We can handle responses by implementing 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 的 ClientLogin 接口的 Google App Engine的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆