The response has the "Set-cookie" header set, which will cause the
user's browser to save the cookie and then present it on the next
request (after redirected by the 302).  In my code I've opted not to
follow the redirect, and extracted the cookie myself, because it's the
urlfetch service doing the request, not the user.  You can then either
return a response to the user with a "Set-cookie" HTTP header (causing
their browser to save the cookie), or handle it some other way (return
it in the body and set the cookie with Javascript, for example).

I think I misunderstood your original question, though, and you're
looking for something different.  You want to get an authorization
cookie and then use it to make repeated requests with urlfetch, not
with a browser?  If that's the case, you're going to want to capture
the "Set-cookie" header from the second response, and supply that in
future requests (setting the "Cookie" header for urlfetch).

Basically, urlfetch will follow redirects but it won't handle cookies
automatically - so what's happening is it's ignoring the "Set-cookie"
header and following the redirect, and being denied because it's not
supplying a cookie.


On Jul 15, 2:58 pm, epb <esbenbu...@gmail.com> wrote:
> I can see why Tony's version would work. His "algorithm" has two
> steps:
>
> 1. Get the authorization token using ClientLogin (which I also managed
> to do).
> 2. Use the uri "servername/_ah/login" to get the auth. cookie.
>
> The appengine_rpc module seems to do authentication in a similar way:
>
> A. Try to access the app. This results in a redirect to a location
> that starts withhttps://www.google.com/accounts/ServiceLogin
> B. Get a auth. token (like step 1 above)
> C. Use auth. token to get auth. cookie.
> D. Try to access the app. again (this is where it fails in my case...)
>
> Anyway, step C is performed using the function below:
>
> -------
>
> def _GetAuthCookie(self, auth_token):
>     """Fetches authentication cookies for an authentication token.
>
>     Args:
>       auth_token: The authentication token returned by ClientLogin.
>
>     Raises:
>       HTTPError: If there was an error fetching the authentication
> cookies.
>     """
>     continue_location = "http://localhost/";
>     args = {"continue": continue_location, "auth": auth_token}
>     login_path = os.environ.get("APPCFG_LOGIN_PATH", "/_ah")
>     req = self._CreateRequest("%s://%s%s/login?%s" %
>                               (self.scheme, self.host, login_path,
>                                urllib.urlencode(args)))
>     try:
>       response = self.opener.open(req)
>     except urllib2.HTTPError, e:
>       response = e
>     if (response.code != 302 or
>         response.info()["location"] != continue_location):
>       raise urllib2.HTTPError(req.get_full_url(), response.code,
> response.msg,
>                               response.headers, response.fp)
>     self.authenticated = True
>
> ------
>
> It seems to me, that we do nothing with the response in this
> function?? Shouldn't we save the cookie in the response like Tony's
> does above, and then use it when we try to log in again?
>
> On Jul 15, 1:06 pm, epb <esbenbu...@gmail.com> wrote:
>
> > Thanks for your answers.
>
> > As I understand Nick's response, I only need to use appengine_rpc.py
> > for the entire process. I tried the following:
>
> > -------
>
> > def passwdFunc():
> >     return ('my_email','my_passwd')
>
> > rpcServer = appengine_rpc.HttpRpcServer
> > ('myapp.appspot.com',passwdFunc,None,'myAppName')
> > blah = rpcServer.Send('/')
>
> > -------
>
> > This gave me a 302 error and the following log:
>
> > -------
>
> > Server: myapp.appspot.com
> > Sending HTTP request:
> > POST /? HTTP/1.1
> > Host: myapp.appspot.com
> > X-appcfg-api-version: 1
> > Content-type: application/octet-stream
>
> > Got http error, this is try #1
> > Got 302 redirect. 
> > Location:https://www.google.com/accounts/ServiceLogin?service=ah&continue=http...
> > nue%3Dhttp://myapp.appspot.com/
> > &ltmpl=gm&ahname=MyAppName&sig=46378246....321321312
> > Sending HTTP request:
> > POST /? HTTP/1.1
> > Host: myapp.appspot.com
> > X-appcfg-api-version: 1
> > Content-type: application/octet-stream
>
> > Got http error, this is try #2
>
> > -------
>
> > It seems to me that the Send() function should do all authentication-
> > work automatically and re-direct to the app page after logging in.
> > Right?
>
> > Anyway, I'll try out Tonys solution also..
>
> > On Jul 15, 11:18 am, Tony <fatd...@gmail.com> wrote:
>
> > > Since I happened to have this up, here's a bit of sample code to get
> > > an authentication cookie for an appspot app...
>
> > > from google.appengine.api import urlfetch
> > > from urllib import urlencode
> > > email = request.POST['username']
> > > passwd = request.POST['password']
> > > serv_root = "http://myapp.appspot.com";
> > > target = 'http://myapp.appspot.com/null'
> > > app_name = "myapp-1.0"
> > > auth_uri = 'https://www.google.com/accounts/ClientLogin'
> > > authreq_data = urlencode({ "Email":   email,
> > >                                   "Passwd":  passwd,
> > >                                   "service": "ah",
> > >                                   "source":  app_name,
> > >                                   "accountType": "HOSTED_OR_GOOGLE" })
> > > result = urlfetch.fetch(auth_uri, authreq_data, method=urlfetch.POST,
> > > follow_redirects=False)
> > > auth_dict = dict(x.split("=") for x in result.content.split("\n") if
> > > x)
> > > auth_token = auth_dict["Auth"]
> > > serv_args = {}
> > > serv_args['continue'] = target
> > > serv_args['auth']     = auth_token
> > > serv_uri = "%s/_ah/login?%s" % (serv_root, urlencode(serv_args))
> > > result2 = urlfetch.fetch(serv_uri, follow_redirects=False,
> > > method=urlfetch.GET)
> > > ### here's the cookie which will authenticate future requests
> > > cookie = result2.headers['set-cookie'].split(';')[0]
> > > # cookie[0] => "ACSID"
> > > # cookie[1] => "AAAAHFSDJHSDFHSDJFHSDJFHSJFSDfsdjfhsjdfhsjdfh..."
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Google App Engine" group.
To post to this group, send email to google-appengine@googlegroups.com
To unsubscribe from this group, send email to 
google-appengine+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/google-appengine?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to