ゲンゾウ用ポストイット

Java、Groovy、Linux関連の備忘録

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

以下のエントリのさらに続き。
facebookにGroovyでログイン(その3) - ゲンゾウ用ポストイット-new

結局、昨日の方式を採用した。
リダイレクト後の http://localhost:9999/#access_token=... の#以降をサーバー側で取得できないため、画面描画後にjavascript?に置き換え再リクエストするようにした。

結果、アクセストークンが取得できた!

#!/usr/bin/env groovy
@Grab("org.mortbay.jetty:jetty-embedded:6.1.26")
import java.lang.reflect.InvocationTargetException
import java.lang.reflect.Method
import javax.servlet.http.*
import javax.servlet.ServletException
import org.mortbay.jetty.Connector
import org.mortbay.jetty.Handler
import org.mortbay.jetty.handler.AbstractHandler
import org.mortbay.jetty.Request
import org.mortbay.jetty.Server


def appId = "XXXXXXXXXXXXXXX"
def localHost = "localhost"
def localPort = 9999

def urltext = "https://www.facebook.com/dialog/oauth?" + [
	            "client_id=${appId}",
	            "redirect_uri=" + URLEncoder.encode("http://${localHost}:${localPort}/login_success.html", "utf-8"),
	            "scope=" + URLEncoder.encode("email,read_stream,friends_about_me,user_about_me", "utf-8"),
	            "response_type=token",
	        ].join("&")

browser = browse(urltext)

server = new Server(localPort).with{
    connectors.each{
        it.host = "${localHost}"
    }

    handler = [
        handle:{ String target, HttpServletRequest request, HttpServletResponse response, int dispatch ->
            switch(target) {
                case "/login_success.html":
                    response.with{
                        status = HttpServletResponse.SC_OK
                        contentType = "text/html"
                        writer.withWriter{
                            it.println("<html>")
                            it.println("<head>")
                            it.println("<script type='text/javascript'>")
                            it.println("function init() {")
                            it.println("    window.location = 'http://localhost:9999/access_token.html?' + window.location.toString().split('#')[1];");
                            it.println("}")
                            it.println("</script>")
                            it.println("</head>")
                            it.println("<body onload=\"init();\">")
                            it.println("</body>")
                            it.println("</html>")
                        }
                        handled = true
                    }
                    break
                case "/access_token.html":
                    println request.getParameter("access_token")
                    println request.getParameter("expires_in")
                    request.handled = true
                    browser.destroy()
                    server.stop()
                    server.join()
                    break
                default:
                    response.status = HttpServletResponse.SC_NOT_FOUND
                    break
            }

        }
    ] as AbstractHandler

    start()
}



def browse(String url) throws ClassNotFoundException, IllegalAccessException,
	    IllegalArgumentException, InterruptedException, InvocationTargetException, IOException,
	    NoSuchMethodException {
	def osName = System.getProperty("os.name", "")
	if (osName.startsWith("Mac OS")) {
	    Class fileMgr = Class.forName("com.apple.eio.FileManager")
	    Method openURL = fileMgr.getDeclaredMethod("openURL", [ String.class ] as Class[])
	    openURL.invoke(null, [ url ] as Object[])
	} else if (osName.startsWith("Windows")) {
	    return Runtime.runtime.exec("rundll32 url.dll,FileProtocolHandler " + url)
	} else {
	    def browser = [ "firefox", "opera", "konqueror", "epiphany", "mozilla", "netscape" ].find{
	        Runtime.runtime.exec([ "which", it ] as String[]).waitFor() == 0
	    }

	    if (!browser)
	        throw new NoSuchMethodException("Could not find web browser")

	    return Runtime.runtime.exec(browser + " ${url}")
	}
}

facebookのアプリケーション設定画面のサイトURL入力欄には、昨日の設定から以下の入力に変更した。

http://localhost:9999/login_success.html

facebook認証後リダイレクトにより、ローカルサーバーのコンテンツが表示されるが、onloadにてすぐに以下のURLにサブミット。

http://localhost:9999/access_token.html


後はトークン取得後のjettyサーバーの停止を組み込みたい。
一応server.stop()メソッドは呼び出しているが停止してくれない。
なぜか一分後とかにひょっこり止まる。

広告を非表示にする