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

2019-03-01Facebook,Groovy,Java

以下のエントリの誤りを修正。

以下のような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.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.protocol.*
import org.apache.http.util.*

HttpClient client = new DefaultHttpClient()
def 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などのサーバーを一時的に起動して、フィルタで処理するようにしようと考えている。

2019-03-01Facebook,Groovy,Java