Code in reference to:
http://groups.google.com/group/google-appengine-java/browse_thread/thread/47306a917b8e1628
I'm not getting back the ACSID Cookie. The comments in the Servlet
Code below explain everything. I hope this helps someone else getting
started because I had a ton of sifting to get to this point.
package com.google.lavards;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.jdo.PersistenceManager;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.net.*;
import javax.jdo.Query;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
@SuppressWarnings("serial")
public class MyGoogleAppServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
try {
/*
* Example Request from a browser:
*
http://localhost:8080/api/v1/[email protected]&merchant_key=TheirPassword
*
* Goal:
* 1. to have user != null and to access
getCurrentUser()'s email
*
* Steps:
* 1. Use merchant_id and merchant_key to
login to the HOSTED
Google account and get an authentication Key
* Http POST to
*
https://www.google.com/accounts/ClientLogin?accountType=HOSTED&service=ah&[email protected]&Passwd=TheirPassword&source=MyGoogleApp
*
* 2. Use the authentication Key from Step
2. to get an ACSID
cookie from Google
* Http GET to
*
http://mygoogleapp.appspot.com/_ah/login?auth=TheResultingAuthKeyFromStep1
*
* 3. Use the resulting ACSID cookie for
the initial request
Redirect to
* (strip off merchant_id and
merchant_key) with Http Header 'Set-
Cookie' = ResultingCookieFromStep2
*
http://localhost:8080/api/v1/merchant
*
* Problem:
* 1. The ACSID cookie is never present,
however a PREF
* Cookie is?? 2. Can't get user
!= null, thus I can't get their
email
*
* Things that work:
* 1. I receive the Auth token from Step 1
Http status 200 (ok)
* 2. I receive a Http status 204 (no
content) for step 2
*
* Future Goals:
* 1. Save the resulting cookie in the
session and reuse it for
future requests over the same session
*
* Comments:
* 1. I know that the Google app
documentation on ClientLogin
says to use the Auth token
* for future requests, but from
all the examples that exclaim
their code is working they had
* to use the Auth token to get
the ACSID Cookie, then they used
that Cookie for future requests.
* 2. I havn't received much help on this
issue. I really hope
posting this code will help others
* suffering from this same
problem. I feel like I could have
been working on things more
* interesting then basic
Authentication problems. Maybe Google
will write a good example
* of proper app Engine
Authentication at some point and include
all of the normal
* path's that are NOT supports.
IE. using the Authentication
Http header, and simply
* getting the Auth token and
passing it in future requests.
*/
UserService userService =
UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
if (user == null) {
// need to authenticate the user
// we don't have our GoogleLogin auth token
// fetch the auth token from google
String loginPath =
"https://www.google.com/accounts/ClientLogin";
String merchantId =
getParameterValueByName(req, "merchant_id");
String merchantKey =
getParameterValueByName(req, "merchant_key");
HttpURLConnection connection = null;
String authKey = null;
if (merchantId == null || merchantKey == null) {
resp.sendError(403,
"[InvalidMerchantException]");
return;
}
loginPath += "?
accountType=HOSTED&service=ah&source=MyGoogleApp&Email=" +
URLEncoder.encode(merchantId, "UTF-8") + "@lava-rds.com&Passwd="
+
URLEncoder.encode(merchantKey, "UTF-8");
try {
URL authUrl = new URL(loginPath);
connection = (HttpURLConnection)
authUrl.openConnection();
connection.setUseCaches(false);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-
form-urlencoded");
connection.connect();
if (connection.getResponseCode() ==
HttpURLConnection.HTTP_OK) {
BufferedReader reader = new
BufferedReader(new InputStreamReader
(connection.getInputStream()));
String line;
while ((line =
reader.readLine()) != null) {
if
(line.contains("Auth=")) {
authKey =
line.replaceFirst("Auth=", "");
}
}
reader.close();
} else {
resp.sendError(HttpURLConnection.HTTP_FORBIDDEN,
"[InvalidMerchantException]");
return;
}
} catch (MalformedURLException e) {
resp.sendError(HttpURLConnection.HTTP_BAD_REQUEST,
"[MalformedURLException]");
return;
} catch (IOException e) {
resp.sendError(HttpURLConnection.HTTP_BAD_REQUEST,
"[IOException]");
return;
} finally {
if (connection != null) {
connection.disconnect();
}
}
// set the google cookie using the auth token
if (authKey == null) {
resp.sendError(HttpURLConnection.HTTP_FORBIDDEN,
"[InvalidMerchantException]");
return;
}
String cookieHeader = null;
try {
String cookiePath =
"http://MyGoogleApp.appspot.com/_ah/login?
auth=" + URLEncoder.encode(authKey, "UTF-8");
URL cookieUrl = new URL(cookiePath);
connection = (HttpURLConnection)
cookieUrl.openConnection();
connection.setUseCaches(false);
connection.setRequestMethod("GET");
connection.connect();
int responseCode =
connection.getResponseCode();
if (responseCode ==
HttpURLConnection.HTTP_NO_CONTENT) {
Map<String, List<String>>
cookies = connection.getHeaderFields
();
for (String cookie :
cookies.keySet()) {
if
(cookie.equalsIgnoreCase("Set-Cookie")) {
//For some
reason the cookie PREF is present, but I noticed it
was
//cutting off
the end of the cookie so I grabbed both 'bites'
and
//combined them
//This is also
where I expect to find the ACSID Cookie, never
present
List<String>
bites = cookies.get(cookie);
for (String
bite : bites) {
if
(cookieHeader == null) {
cookieHeader = bite;
} else {
cookieHeader += bite;
}
}
}
}
} else {
resp.sendError(HttpURLConnection.HTTP_FORBIDDEN,
"[InvalidMerchantException]");
return;
}
} catch (MalformedURLException e) {
resp.sendError(HttpURLConnection.HTTP_BAD_REQUEST,
"[MalformedURLException]");
return;
} catch (IOException e) {
resp.sendError(HttpURLConnection.HTTP_BAD_REQUEST,
"[IOException]");
return;
} finally {
if (connection != null) {
connection.disconnect();
}
}
if (cookieHeader == null) {
resp.sendError(HttpURLConnection.HTTP_FORBIDDEN,
"[InvalidMerchantException] Cookie is null.");
return;
}
String destPath = req.getQueryString();
//strip off the merchant_id and merchant_key
destPath =
destPath.replaceFirst("(&)?merchant_id=" + merchantId,
"");
destPath =
destPath.replaceFirst("(&)?merchant_key=" +
merchantKey, "");
//go ahead and append auth key, just incase it
is required...
destPath += "&auth=" + authKey;
String destUrl = req.getRequestURI() + "?" +
destPath;
//if ?& replace it with ?
destUrl = destUrl.replaceFirst("\\?&", "?");
resp.addHeader("Set-Cookie", cookieHeader);
//resp.addHeader("Cookie", cookieHeader);
resp.sendRedirect(destUrl);
return;
} else {
// user was authenticated, GOAL COMPLETE!
resp.setContentType("text/plain");
resp.getWriter().print(user.getEmail());
}
} catch (Exception ex) {
resp.sendError(HttpURLConnection.HTTP_BAD_REQUEST,
"[InternalTransactionException]");
}
}
private String getParameterValueByName(HttpServletRequest req, String
name) {
try {
String ret = null;
Map<String, String[]> parameterMap =
req.getParameterMap();
if (parameterMap.containsKey(name)) {
ret = parameterMap.get(name)[0];
}
return ret;
} catch (Exception ex) {
return null;
}
}
}
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Google App Engine for Java" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/google-appengine-java?hl=en
-~----------~----~----~----~------~----~------~--~---