Search code examples
javahttpclientlinkedin-apijsoup

Login to LinkedIn by using username and password failed


LinkedIn uses oauth to login to its api.There is no way to login to api in server.I tried to use http request to login into linkedin and get oauth_verifier,but I got response like this

We’re sorry, there was a problem with your request. Please make sure you have cookies enabled and try again.

Or follow this link to return to the home page.

I have analyze the communicate between my browser and server many times,but still could't find why

  public boolean Login(String user, String pass, String url) {
    try {
        DefaultHttpClient httpclient;
        HttpParams params = new BasicHttpParams();
        ConnManagerParams.setMaxTotalConnections(params, 100);
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);

        // Create and initialize scheme registry
        SchemeRegistry schemeRegistry = new SchemeRegistry();
        schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
        // Create an HttpClient with the ThreadSafeClientConnManager.
        // This connection manager must be used if more than one thread will
        // be using the HttpClient.
        ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
        httpclient = new DefaultHttpClient(cm, params);

        String loginHTML = httpSession.Get(url);

        for (Cookie c : httpSession.cs.getCookies()) {
            httpclient.getCookieStore().addCookie(c);
        }

        Document doc = Session.GetDocument(loginHTML, url);
        HashMap<String, String> hm = new HashMap<String, String>();
        String postURL = doc.getElementsByAttributeValue("name", "oauthAuthorizeForm").get(0).absUrl("action");
        HttpResponse response;
        HttpEntity entity;
        HttpPost httpost = new HttpPost(postURL);
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        hm.put("session_login", user);
        hm.put("session_password", pass);
        hm.put("duration", "0");
        hm.put("authorize", "Ok, I&apos;ll Allow It");
        hm.put("extra", doc.getElementsByAttributeValue("name", "extra").get(0).attr("value"));
        hm.put("access", doc.getElementsByAttributeValue("name", "access").get(0).attr("value"));
        hm.put("agree", "true");
        hm.put("oauth_token", doc.getElementsByAttributeValue("name", "oauth_token").get(0).attr("value"));
        hm.put("appId", doc.getElementsByAttributeValue("name", "appId").get(0).attr("value"));
        hm.put("csrfToken", doc.getElementsByAttributeValue("name", "csrfToken").get(0).attr("value"));
        hm.put("sourceAlias", doc.getElementsByAttributeValue("name", "sourceAlias").get(0).attr("value") + "session_login=" + user);


        for (Entry<String, String> i : hm.entrySet()) {
            nvps.add(new BasicNameValuePair(i.getKey(), new String(i.getValue().getBytes(), "utf-8")));
        }
        hm.put("sourceAlias", doc.getElementsByAttributeValue("name", "sourceAlias").get(0).attr("value"));
        for (Entry<String, String> i : hm.entrySet()) {
            nvps.add(new BasicNameValuePair(i.getKey(), new String(i.getValue().getBytes(), "utf-8")));
        }

        httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
        httpost.setHeader("User-Agent", "Shisoft NetFusion");
        response = httpclient.execute(httpost);
        entity = response.getEntity();


        Header headers[] = response.getHeaders("location");
        for (Header h : headers) {
            if (!h.getValue().isEmpty()) {
                String newurl = h.getValue();
                String oauthVerifier = newurl.split("oauth_verifier=")[1].split("&")[0];
                accessToken = oauthService.getOAuthAccessToken(requestToken, oauthVerifier);
                return true;
            }
        }
        if (entity != null) {
            String resHTML = EntityUtils.toString(entity);
            //entity.getContent().close();
            httpost.abort();
            httpclient.getConnectionManager().closeExpiredConnections();
        }

        httpost.abort();
        return false;
    } catch (Exception ex) {
        Logger.getLogger(ClassLinkedIn.class.getName()).log(Level.SEVERE, null, ex);
    }
    return false;
}

the url is AuthorizationUr httpSession.Get(url); gets the login page and cookies.


Solution

  • I use HTMLUnit solved this issue.

       public boolean Login(String user, String pass, String url) {
            try {
                final WebClient webClient = new WebClient();
    
                // Get the first page
                final HtmlPage page1 = webClient.getPage(url);
    
                // Get the form that we are dealing with and within that form,
                // find the submit button and the field that we want to change.
                final HtmlForm form = page1.getFormByName("oauthAuthorizeForm");
    
                final HtmlSubmitInput button = form.getInputByName("authorize");
                final HtmlTextInput textField = form.getInputByName("session_login");
                final HtmlPasswordInput textField2 = form.getInputByName("session_password");
                // Change the value of the text field
                textField.setValueAttribute(user);
                textField2.setValueAttribute(pass);
    
                // Now submit the form by clicking the button and get back the second page.
    
                final HtmlPage page2 = button.click();
                String newurl = page2.getUrl().toString();
                String oauthVerifier = newurl.split("oauth_verifier=")[1].split("&")[0];
                accessToken = oauthService.getOAuthAccessToken(requestToken, oauthVerifier);
    
                webClient.closeAllWindows();
                logined = true;
                return true;
    
            } catch (Exception ex) {
                Logger.getLogger(ClassLinkedIn.class.getName()).log(Level.SEVERE, null, ex);
            }
            return false;
        }
    

    But remember,you need to use the last version of HTMLUnit,not the release on sf.net This also is not a perfect solution.It works,but cost a lot on javascript\css inside the webpages and others