首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android -谷歌登录网络API -如何发送谷歌登录后的请求?

Android -谷歌登录网络API -如何发送谷歌登录后的请求?
EN

Stack Overflow用户
提问于 2014-05-01 13:08:46
回答 1查看 1.2K关注 0票数 2

我有一个机器人项目,允许我使用登录Google-帐户。一切正常工作,我可以检索个人(com.google.android.gsm.model.people.Person)的数据,如谷歌电子邮件,用户名,个人资料图片网址等。

我还有一个在线托管的Web。在这个Web中,我可以使用以下方法获得一个JSON产品列表:mywebhost/api/products

显然,这些get请求是由OAuth 2.0授权的,这意味着我必须登录到mywebhost/Account/Login页面上的一个Google,才能从Web获得JSON列表。(当我没有登录时,我会收到以下JSON列表:{"$id":"1","Message":"Authorization has been denied for this request."})

我知道如何用Android发送帖子请求。例如,使用代码:

代码语言:javascript
复制
public class TaskPostAPI extends AsyncTask<String, Void, String>
{   
    GoogleApiClient googleAPI;

    public TaskPostAPI(GoogleApiClient googleAPI){
        this.googleAPI = googleAPI;
    }

    @Override
    protected String doInBackground(String... urls){
        String response = "";
        for(String url : urls){
            DefaultHttpClient client = new DefaultHttpClient();
            HttpPost post = new HttpPost(url);
            try{
                List<NameValuePair> nvPairs = new ArrayList<NameValuePair>(3);
                //nvPairs.add(new BasicNameValuePair("personName", Plus.PeopleApi.getCurrentPerson(googleAPI).getDisplayName()));
                //nvPairs.add(new BasicNameValuePair("personGooglePlusProfile", Plus.PeopleApi.getCurrentPerson(googleAPI).getUrl()));
                //nvPairs.add(new BasicNameValuePair("personEmail", Plus.AccountApi.getAccountName(googleAPI)));

                // TODO: Use the correct nvPairs to be able to Log-in with the Google-account

                post.setEntity(new UrlEncodedFormEntity(nvPairs));

                HttpResponse execute = client.execute(post);
                InputStream content = execute.getEntity().getContent();

                BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
                String s = "";
                while((s = buffer.readLine()) != null)
                    response += s;
            }
            catch(Exception ex){
                ex.printStackTrace();
            }
        }
        return response;
    }

    @Override
    protected void onPostExecute(String result){
        // Do nothing yet
    }
}

所以,现在的问题是:

  1. 在上面的代码示例中,nvPairs应该能够成功地登录到Google帐户中。或者,我应该使用与普通HttpPost完全不同的方式登录到我的Web上的Google帐户中吗?
  2. 另外:提供的url是默认的登录页面。在这个页面上,我有三个不同的选项要登录。既然我们只想使用Google登录,那么我如何从Web登录页面中检索Google登录按钮的url,以便在后请求中使用?

2b。关于第二个问题:我可以在FireFox中使用什么插件来查看重定向到的链接?因此,我知道应该使用哪个登录url而不是默认的登录页。

提前感谢您的回复。

编辑1:我尝试过一种不同的方法,但我不确定它是否适用于HttpGet请求。我尝试的是使用登录页打开一个WebView,当我成功登录时到达页面后,我就关闭WebView。

但是,当我使用HttpGet请求时,我仍然会得到未经授权的JSON,那么如何使用这个WebView登录来使HttpGet请求“相信”我已经登录并授权了呢?

如果有人仍然有使用第一种方法(HttpPost-request)的想法,或者如果有人有一种完全不同的方法,请告诉我。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-05 07:42:15

好的,我已经找到了可以在POST web项目(/POST/ExternalLogin)中使用的C#。在那里我也看到了我应该发送的内容:

header

  • 内容-类型应用程序/x-www-表单-urlencoded
  • 带__RequestVerificationToken的Cookie

body

  • 提供商(“谷歌”)
  • returnUrl
  • __RequestVerificationToken

第二个__RequestVerificationToken需要不同于Cookie中使用的那个,但是在C# Web中解密它之后,它应该是相同的。这是我现在唯一的问题,但我有一个不同的堆叠溢出问题。

关于完整的代码:

代码语言:javascript
复制
public class TaskPostAPI extends AsyncTask<String, Void, String>
{
    private String TOKEN = "__RequestVerificationToken";

    @Override
    protected String doInBackground(String... urls){
        String response = "";
        for(String url : urls){
            HttpPost post = new HttpPost(url);
            try{
                // Add the default Content-type to the Header
                post.addHeader("Content-type", "application/x-www-form-urlencoded");

                // Get the baseUrl from the given url
                URL u = new URL(url);
                String baseUrl = u.getProtocol() + "://" + u.getHost();

                // POST-request requires anti-forgery Cookie
                // Get all Cookies
                CookieManager cookieManager = CookieManager.getInstance();
                String cookie = cookieManager.getCookie(baseUrl);
                String[] cookies = cookie.split(";");

                // Put all Cookies in a HashMap with cookieKey & cookieToken
                HashMap<String, String> cookieStrings = new HashMap<String, String>();
                for(String cook : cookies){
                    String[] cs = cook.split("=");
                    cookieStrings.put(cs[0], cs[1]);
                }

                // Add the Cookie to the Header
                post.addHeader("Cookie", TOKEN + "=" + cookieStrings.get(TOKEN) + "");

                // POST-request requires cookieToken, provider and returnUrl
                List<NameValuePair> nvPairs = new ArrayList<NameValuePair>(3);
                nvPairs.add(new BasicNameValuePair(TOKEN, cookieStrings.get(TOKEN)));
                nvPairs.add(new BasicNameValuePair("provider", "Google"));
                nvPairs.add(new BasicNameValuePair("returnUrl", baseUrl));
                post.setEntity(new UrlEncodedFormEntity(nvPairs));

                Log.i("COOKIE OUTPUT", TOKEN + "=" + cookieStrings.get(TOKEN) + "");

                // Send the POST-request
                HttpResponse execute = MainActivity.HttpClient.execute(post);

                // Get the response of the POST-request
                InputStream content = execute.getEntity().getContent();
                BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
                String s = "";
                while((s = buffer.readLine()) != null)
                    response += s;
            }
            catch(Exception ex){
                ex.printStackTrace();
            }
        }
        return response;
    }

在这段代码中,下面的一行是不正确的,仍然需要修复:

nvPairs.add(new BasicNameValuePair(TOKEN, cookieStrings.get(TOKEN)));

需要用要发送的正确令牌替换cookieStrings.get(TOKEN)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23408335

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档