There's an echo in my head

日々のメモ。

WebMockでスタブしつつSSLのOpenID認証を使う

結論からいうと

WebMockでHTTP通信をスタブしつつとSSLOpenID認証を使う場合には次のようにWebMockを設定する必要がある:

WebMock.allow_net_connect!(net_http_connect_on_start: true)

どういうことかというと

ruby-openidはidentifierがSSLhttps://から始まる)の場合に、事前に通信できるかどうかをチェックしてる。実装としてはこのあたり

そしてそれはNet::HTTP#startNet::HTTP#connectが呼ばれていることを前提としている。もし呼ばれていない場合には@socketがセットされていないので、次のようなエラーが出る:

OpenID::DiscoveryFailure: Failed to fetch identity URL https://xxxxxx/ : Error fetching https://xxxxxx/: undefined method `io' for nil:NilClass

で、WebMockではREADMEにある通り、デフォルトだとNet::HTTP#startを上書きしてconnectを呼ばないようにしている。なので、WebMockをrequireしたままだとOpenIDの事前チェックに失敗してしまう。

というわけで、connectを呼ぶようにするために前述のオプションが必要になる。

WebMock.allow_net_connect!(net_http_connect_on_start: true)

ちなみにomniauth-openidだと上の例外に対して次のようなシンプルなエラーログが吐かれるだけなのでちょっとわかりづらい。

ERROR -- omniauth: (some_provider) Authentication failure! connection_failed encountered.
このブログに出てくるコードスニペッツは、引用あるいは断りがない限りMITライセンスです。