GAE on jRuby で Google アカウント認証をやってみる
GAE on jRuby with Sinatra でやってみるよ
元ネタは Users Java API の概要 - Google App Engine — Google Developers で、こいつを jRuby 上で sinatra を使った場合どうやるのか? という話。
ポイントは 2点
- Java のスタティッククラスを使う場合は import 文を使う
- Java の HttpServletRequest オブジェクトを取得する場合は、 sinatra の request オブジェクトの Hash に格納されている
この二つを踏まえればあとはそのまま移植すれば良い。
サンプルアプリはこちら
ログインしていない場合は、ログイン用のリンクが出ます。ログインすると、各種の情報を出力します。
見た目がダサイのはご了承下さいw
ちなみに、一つだけ良くわからない点があるのだけど、isUserAdmin() が true を返す条件がわからない。何を持って Admin として判断しているの???
その他:Returning nil _server と言われて困る><
Mac の Leopard 付属の screen を使っていると、デプロイ時の appcfg.rb でパスワードを聞かれる場面で動作が重くてどうにもなくなる、という現象がある。
screen を辞める or MacPorts 経由での GNU screen を使っているとでないらしい。*1
参考:GNU screenで「Returning nil _server」といわれた場合の対処法 - Hello, world! - s21g
ソースはこんな感じ
config.ru
catrequire 'appengine-rack' require 'app' AppEngine::Rack.configure_app( :application => "hogehoge", :version => xx ) run Sinatra::Application
:application とかは適宜変えてね
app.rb
catrequire 'rubygems' require 'sinatra' # Java のスタティックなクラスを使う為には import しておく必要がある include Java import com.google.appengine.api.users.UserServiceFactory; template :layout do <<-EOS <html> <head> <title><%= @title %></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <h1><%= @title %></h1> <ul><%= @message %></ul> <hr /> <%= yield %> </body> </html> EOS end get '/' do @title = "GAE sample" @message = "GAE sample" @body = '' @body << '<ul>' @body << '<li><a href="/user_sample">Google アカウント Java API 概要のjRuby での実装サンプル</a></li>' @body << '</ul>' erb %{ <%= @body %><br /> } end get '/user_sample' do @title = "google認証実験" @message = '<a href="http://code.google.com/intl/ja/appengine/docs/java/users/overview.html">Google アカウント Java API 概要</a>のjRuby での実装サンプル' userService = UserServiceFactory.getUserService(); puts userService servlet = request.env["java.servlet_request"] if(servlet.getUserPrincipal) user = userService.currentUser() principal = servlet.getUserPrincipal() @body = "" # getUserService() で取得した UserService オブジェクト @body << "<h2>UserServiceFactory.getUserService()で取得した <a href='http://code.google.com/intl/ja/appengine/docs/java/javadoc/com/google/appengine/api/users/UserService.html'>UserService オブジェクト</a></h2>" @body << "isUserAdmin():#{userService.isUserAdmin()}<br />" @body << "isUserLoggedIn():#{userService.isUserLoggedIn()}<br />" @body << "<hr />" # currentUser() で取得した User オブジェクト @body << "<h2>UserServiceFactory.getUserService().currentUser() で取得した <a href='http://code.google.com/intl/ja/appengine/docs/java/javadoc/com/google/appengine/api/users/User.html'>User オブジェクト</a></h2>" @body << "getNickname():#{user.getNickname()}<br />" @body << "getAuthDomain():#{user.getAuthDomain()}<br />" @body << "getEmail():#{user.getEmail()}<br />" @body << "<hr />" # HttpServletRequest オブジェクトから取得した Principal オブジェクト @body << "<h2>request.env['java.servlet_request'].getUserPrincipal() で取得した <a href='http://sdc.sun.co.jp/java/docs/j2se/1.4/ja/docs/ja/api/java/security/Principal.html'>Principal オブジェクト</a></h2>" @body << "getName():#{principal.getName()}" @body << "<hr />" # ログアウトリンク @body << "<a href='#{userService.createLogoutURL(servlet.getRequestURI)}'>logout</a>" else # ログインリンク @body = "<a href='#{userService.createLoginURL(servlet.getRequestURI)}'>login</a>" end erb %{ <%= @body %><br /> } end
複数ファイルにする程でもないと思ったので ERB でソース内にべた書き。とりあえず奇麗さとかは目を瞑っていますw
あと、気になる点
GAE そのものの話なんだけど、一度作った My Applications のリソースって削除できないんですかね。10個しか作れないみたいなので慎重に使いたいのだけど、盛大に typo してなんとか闇に葬りたいのが一つあるんですけど><
*1:一時、これで半狂乱になったw