ゲンゾウ用ポストイット

Java、Groovy、Linux関連の備忘録

facebookにGroovyでログイン(その2)

以下のエントリの誤りを修正。
facebookにGroovyでログイン - ゲンゾウ用ポストイット-new


以下のようなhttpアクセスを実装した。

  1. facebookのログイン画面へアクセス
  2. ユーザー名、パスワードを指定しfacebookへログイン
  3. ログイン完了後、OAuth認証用のURLへ所定のパラメータを指定しGetアクセス
  4. facebookアプリを認証を許可する画面が表示されるため、ログインボタンを押す

ちなみに上記の最後の処理がうまくどうさしていない。

#!/usr/bin/env groovy
@Grab("org.apache.httpcomponents:httpclient:4.1.2")
import org.apache.http.*
import org.apache.http.client.*
import org.apache.http.protocol.*
import org.apache.http.client.entity.*
import org.apache.http.client.methods.*
import org.apache.http.client.params.*
import org.apache.http.impl.client.*
import org.apache.http.message.*
import org.apache.http.util.*


def res = null
HttpClient client = new DefaultHttpClient()


res = client.execute(new HttpGet("https://www.facebook.com/login.php"))
def nextAction =  res.entity.content.text.replaceAll(/(?msi).+<form method="post".+?action="(.+?)"[^>]*>.+/, "\$1")
EntityUtils.consume(res.entity)


HttpPost post2 = new HttpPost(nextAction)
post2.entity = new UrlEncodedFormEntity([
    new BasicNameValuePair("email", "genzouw@gmail.com"),
    new BasicNameValuePair("pass", "XXXXXXXXXX")
], HTTP.UTF_8)
res = client.execute(post2)
EntityUtils.consume(res.entity)


def urltext = "https://www.facebook.com/dialog/oauth?" + [
                "client_id=XXXXXXXXXXXXXXXXXXXX",
                "redirect_uri=" + URLEncoder.encode("https://www.facebook.com/connect/login_success.html", "utf-8"),
                "scope=" + URLEncoder.encode("email,read_stream,friends_about_me,user_about_me", "utf-8"),
                "response_type=token",
            ].join("&")
res = client.execute(new HttpGet(urltext))
res.entity.content.text
EntityUtils.consume(res.entity)


HttpPost postLast = new HttpPost("https://www.facebook.com/dialog/permissions.request")
postLast.entity = new UrlEncodedFormEntity([
    new BasicNameValuePair("grant_required_cliked", ""),
], HTTP.UTF_8)
res = client.execute(postLast)
println res.entity.content.text
println res.statusLine.statusCode
def locations = res.getHeaders("location")
EntityUtils.consume(res.entity)


client.connectionManager.shutdown()


以下のGrab定義部分で利用しているhttpcomponentsライブラリの使い方に多くの誤りがあった。

@Grab("org.apache.httpcomponents:httpclient:4.1.2")


まず、HttpClientインスタンスは毎回生成する必要がない。
毎回インスタンス生成をしないとエラーとなっていたが、それはHttpResponse#getEntityで取得したHttpEntityインスタンスのabortをしていなかったことが原因。
以下のようにEntityUtils#comsumeメソッドを利用してクローズすることで問題が発生しなくなった。

EntityUtils.consume(res.entity)

加えて、毎回HttpClientインスタンスを生成しなくなったため、cookieStoreインスタンスをセットする必要もなくなった。
(HttpClientインスタンス内で保持してくれている模様。HttpClientインスタンス生成時に空のそれを内部に保持しているようだ。)


というか、OAuth2.0の認証をブラウザなしで利用するのはかなりしんどい。
accessToken取得までの流れは、jettyなどのサーバーを一時的に起動して、フィルタで処理するようにしようかなと思い中。

広告を非表示にする