문제

I've got an Android project that allows me to log-in with Google-accounts. Everything works as it's supposed to and I'm able to retrieve the Person's (com.google.android.gsm.model.people.Person) data, like Google email, username, profile picture url, etc.

I also have a Web API hosted online. In this Web API I can get a JSON-list of products by using the following: mywebhost/api/products.

Obviously these GET-requests are Authorized by OAuth 2.0, meaning I have to log-in with a Google Account on the mywebhost/Account/Login page to be authorized to get the JSON-list from the Web API. (When I'm not logged in, I receive the following JSON-list: {"$id":"1","Message":"Authorization has been denied for this request."})

I know how to send POST-requests in Android. For example with the code:

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
    }
}

So, now the question:

  1. In the code sample above, what should the nvPairs be to be able to successfully log-in with a Google-account. Or should I use something completely different than normal HttpPost to log-in with a Google-account on my Web API?
  2. Also: The url provided is the default Log-in page. On this page I have three different options to log-in. Since we only want to use the Google log-in, how can I retrieve the url of the Google Log-in button from the Web API Login-page to use for the POST-request?

2b. With the second question: What Plug-in I could use in FireFox to see the links I'm redirected to? So I know which Login-url I should use instead of the default Login-page.

Thanks in advance for the responses.


Edit 1: I've tried a different approach, but I'm not sure it will work for the HttpGet-requests. What I've tried is opening a WebView with the Log-in page, and after I reach the page where I come when I successfully logged-in, I close the WebView.

However, when I use the HttpGet-requests, I still get the Unauthorized JSON back, so how can I use this WebView Log-in to make the HttpGet-request "believe" I'm logged-in and Authorized?

If someone still has an idea using the first approach (HttpPost-request), or if someone has a completely different approach, let me know.

도움이 되었습니까?

해결책

Ok, I've found the POST I can use in the C# web project (/POST/ExternalLogin). There I also see what I should send:

In the header:

  • Content-Type application/x-www-form-urlencoded
  • Cookie with __RequestVerificationToken

In the body:

  • provider ("Google")
  • returnUrl
  • __RequestVerificationToken

The second __RequestVerificationToken needs to be a different one than the one used in the Cookie, but after decrypting it in the C# Web API it should be the same. This is the only problem I have right now, but I've got a different stackoverflow question for that.

For the full code:

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;
    }

In this piece of code the following line is incorrect and still needs fixing:

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

cookieStrings.get(TOKEN) need to be replaced with the correct token to send.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top