$shibayu36->blog;

株式会社はてなでエンジニアをしています。プログラミングや読書のことなどについて書いています。

[perl]Mojolicious::Plugin::CSRFDefenderが動かなかった件

 久々にチェックしてみたらMojolicious::Plugin::CSRFDefenderのテストが全く通っていなかったので、調べてみました。

原因

 原因はMojoliciousが1.1か1.2くらいに更新したときに、after_dispatchのhookがsessionをストアした後に動作するようになっていたため、sessionに内容を入れることができなくなっていたためでした。Mojolicous::Controllerのrenderedメソッドの部分です。

sub rendered {
  my ($self, $status) = @_;

  # Disable auto rendering
  $self->render_later;

  # Make sure we have a status
  my $res = $self->res;
  $res->code($status) if $status;

  # Finish transaction
  my $stash = $self->stash;
  unless ($stash->{'mojo.finished'}) {
    $res->code(200) unless $res->code;
    my $app = $self->app;
    $app->sessions->store($self); # これが先にあるため、after_dispatch hook内部でsessionをいじっても反映されない
    $app->plugins->run_hook_reverse(after_dispatch => $self);
    $stash->{'mojo.finished'} = 1;
  }
  $self->tx->resume;

  return $self;
}

修正

 Mojoliciousの作者の方に修正を送ってみたところ、

  1. バグ修正って言ってるけど、これはバグ修正ではなく、新しい仕様だよね
  2. その場合ちゃんとテストを書いてほしい

と、怒られた上で反映していただきました。当然のことですね...今後は気をつけます。

 というわけで、Mojoliciousの1.43からはMojolicious::Plugin::CSRFDefenderが動作するようになります。その前に使いたい方はhttps://github.com/kraih/mojoからMojoliciousを入れて、利用してください。