FacebookにGroovyでログイン(その2)
以下のエントリの誤りを修正。
以下のようなhttpアクセスを実装した。
- Facebookのログイン画面へアクセス
- ユーザー名、パスワードを指定しFacebookへログイン
- ログイン完了後、OAuth認証用のURLへ所定のパラメータを指定しGetアクセス
- 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などのサーバーを一時的に起動して、フィルタで処理するようにしようと考えている。
ディスカッション
コメント一覧
まだ、コメントがありません