android - 从android客户端登录到appengine

标签 android google-app-engine authentication

我正在尝试登录应用引擎到应用引擎并访问应用引擎中的用户服务 API。基本上我希望能够看到谁登录了我的 servlet。我正在使用从 android 获取 authtoken 然后从应用引擎获取 ASID(或 SACID)cookie 的身份验证流程。然后将 cookie 与 http 请求一起发送到 appengine servlet。这似乎一切正常,但是当我尝试使用此代码获取用户时:

UserService userService = UserServiceFactory.getUserService();
User user= userService.getCurrentUser();

用户始终为空。我的问题是我在这里遗漏了什么吗?为什么用户服务返回空用户?下面是我的 appengine 和 android 代码。任何帮助将不胜感激!

应用引擎:

public class MyServlet extends HttpServlet {

public void process(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
 resp.setContentType("text/plain");

 UserService userService = UserServiceFactory.getUserService();
User user= userService.getCurrentUser();    
 }

public void doPost(HttpServletRequest req, HttpServletResponse resp)
 throws IOException, ServletException {
process(req, resp);
 }

public void doGet(HttpServletRequest req, HttpServletResponse resp)
 throws IOException, ServletException {
 process(req, resp);
 }
}

安卓代码:

public class AppEngineClient {
static final String BASE_URL = Util.getBaseUrl(this);
private static final String AUTH_URL = BASE_URL + "/_ah/login";
private static final String AUTH_TOKEN_TYPE = "ah";

private final Context mContext;
private final String mAccountName;

private static final String TAG = "AppEngineClient";

public AppEngineClient(Context context, String accountName) {
    this.mContext = context;
    this.mAccountName = accountName;
}

public HttpResponse makeRequest(String urlPath, List<NameValuePair> params) throws Exception {
    HttpResponse res = makeRequestNoRetry(urlPath, params, false);
    if (res.getStatusLine().getStatusCode() == 500) {
        res = makeRequestNoRetry(urlPath, params, true);
    }
    return res;
}

private HttpResponse makeRequestNoRetry(String urlPath, List<NameValuePair> params, boolean newToken)
        throws Exception {
    // Get auth token for account
    Account account = new Account(mAccountName, "com.google");
    String authToken = getAuthToken(mContext, account);

    if (newToken) {  // invalidate the cached token
        AccountManager accountManager = AccountManager.get(mContext);
        accountManager.invalidateAuthToken(account.type, authToken);
        authToken = getAuthToken(mContext, account);
    }

    // Get SACSID cookie
    DefaultHttpClient client = new DefaultHttpClient();
    String continueURL = BASE_URL;
    URI uri = new URI(AUTH_URL + "?continue=" +
            URLEncoder.encode(continueURL, "UTF-8") +
            "&auth=" + authToken);
    HttpGet method = new HttpGet(uri);
    final HttpParams getParams = new BasicHttpParams();
    HttpClientParams.setRedirecting(getParams, false);  // continue is not used
    method.setParams(getParams);

    HttpResponse res = client.execute(method);
    Header[] headers = res.getHeaders("Set-Cookie");
    if (res.getStatusLine().getStatusCode() != 302 ||
            headers.length == 0) {
        return res;
    }

    String sascidCookie = null;
    for (Header header: headers) {
        if (header.getValue().indexOf("SACSID=") >=0) {
            // let's parse it
            String value = header.getValue();
            String[] pairs = value.split(";");
            ascidCookie = pairs[0];
        }
    }

    // Make POST request
    uri = new URI(BASE_URL + urlPath);
    HttpPost post = new HttpPost(uri);
    UrlEncodedFormEntity entity =
        new UrlEncodedFormEntity(params, "UTF-8");
    post.setEntity(entity);
    post.setHeader("Cookie", ascidCookie);
    post.setHeader("X-Same-Domain", "1");  // XSRF
    res = client.execute(post);
    return res;
}

private String getAuthToken(Context context, Account account) throws PendingAuthException {
    String authToken = null;
    AccountManager accountManager = AccountManager.get(context);
    try {
        AccountManagerFuture<Bundle> future =
                accountManager.getAuthToken (account, AUTH_TOKEN_TYPE, false, null, null);
        Bundle bundle = future.getResult();
        authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN);
        if (authToken == null) {
            throw new PendingAuthException(bundle);
        }
    } catch (OperationCanceledException e) {
        Log.w(TAG, e.getMessage());
    } catch (AuthenticatorException e) {
        Log.w(TAG, e.getMessage());
    } catch (IOException e) {
        Log.w(TAG, e.getMessage());
    }
    return authToken;
}

public class PendingAuthException extends Exception {
    private static final long serialVersionUID = 1L;
    private final Bundle mAccountManagerBundle;
    public PendingAuthException(Bundle accountManagerBundle) {
        super();
        mAccountManagerBundle = accountManagerBundle;
    }

    public Bundle getAccountManagerBundle() {
        return mAccountManagerBundle;
    }
}

最佳答案

上面的 Android 代码从 Google Accounts API 获取 ClientLogin token 。要通过 UserService 登录和获取当前用户,GAE 应用程序也必须使用 Google Accounts API 进行身份验证(“应用程序设置”->“身份验证选项”)。

关于android - 从android客户端登录到appengine,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9811730/

相关文章:

java - 在 Java 中用内部类拆分大类

google-app-engine - 部署应用程序时出现 Google Cloud SDK 错误 : error 403 operation not allowed

google-app-engine - 谷歌应用引擎上的大量 http 请求出现 "reached maximum number of connections"错误

html - firefox 将密码填入用户名字段

asp.net - Azure 与 owin 和 web.config 中的授权

java - 如何使用 "android.animation"包为平板电脑创建基本图像动画

android - 无法获取 introspy.db 文件

java - 查找图像 OpenCV Android SDK 中的颜色百分比

java - 更新 Google App Engine 模块

Django Rest JWT 身份验证 - 刷新 token