요즘 새로운 아이디어가 생기면 Sinatra부터 찾게 된다. 작은 코드와 깔끔한 DSL로 코딩하는 맛이 있기 때문일 것 같다.
그런데 딱 하나 아쉬운 점이 있다면, 바로 레일스의 수많은 플러그인들이다. 다행히 요즘은 Merb나 Sinatra같은 프레임워크를 위해서 플러그인을 젬으로 제작하는 일도 많지만, 아직은 레일스 전용 플러그인이 훨씬 많다. 아, 이거 X 플러그인 설치만 하면 끝인데, 라는 생각을 하면서 구현을 하는 맛은 그리 유쾌하지 못하다.
오늘은 오픈아이디 RP(Relaying Party)를 만들어야하는데, 이전에 만들어둔 5분만에 만드는 레일스 오픈아이디 인증 - OpenIdAuthentication 플러그인이 떠올랐다. 그래서 간단하게 Sinatra로 포팅을 했다.
뭐 그리 대단한 코드도 아니다. OpenIdAuthentication라는 모듈을 만들고 이 모듈을 EventContext에 포함시켰다.
- module OpenIdAuthentication
#....
- end
- Sinatra::EventContext.send :include, OpenIdAuthentication
그리고 액션 URL을 등록해줬다.
- Sinatra.application.define_event(:post, '/openid/begin') do
begin_openid_authentication(params[:openid_identifier])
end
Sinatra.application.define_event(:post, '/openid/complete') do
complete_openid_authentication
end
전체 소스 코드는 http://github.com/deepblue/snippets/tree/master/sinatra/lib/openid_authentication.rb에서 확인할 수 있다.
그리고 아래는 이 모듈을 사용한 간단한 예제 애플리케이션 소스다.
- # OpenID Consumer sample application built with sinatra
# by deepblue (http://myruby.net)
%w(rubygems sinatra haml).each{|lib| require lib}
get '/' do
haml :login
end
load File.dirname(__FILE__) + '/lib/openid_authentication.rb'
module OpenIdAuthentication
def authentication_succeed(oidresp)
nickname = sreg_data(oidresp)['nickname']
@message = "Logged in as #{nickname}(#{oidresp.display_identifier})"
haml :login
end
def authentication_failed(oidresp, message)
@message = "FAILED!!"
haml :login
end
def sreg_request
OpenID::SReg::Request.new(%w(nickname))
end
end
use_in_file_templates!
__END__
## layout
%html
%body
=yield
## login
%h1= @message || 'Login'
%form{:action => '/openid/begin', :method => 'post'}
%input{:name => 'openid_identifier'}
%input{:type => 'submit'}
