読者です 読者をやめる 読者になる 読者になる

end0tknr's kipple - 新web写経開発

http://d.hatena.ne.jp/end0tknr/ から移転します

perlのAmon2でajaxすると、403 Forbidden ( XSRF detected )

どうやら、Amon2では、Amon2::Plugin::Web::CSRFDefender によるCSRF防止機能があるらしく、具体的には、次のように実装されています。

package SampleApp::Web::Plugin::Session;
  :
sub init {
    my ($class, $c) = @_;

    # Validate XSRF Token.
    $c->add_trigger(
        BEFORE_DISPATCH => sub {
            my ( $c ) = @_;
            if ($c->req->method ne 'GET' && $c->req->method ne 'HEAD') {
                my $token =
                    $c->req->header('X-XSRF-TOKEN') || $c->req->param('XSRF-TOKEN');
                unless ($c->session->validate_xsrf_token($token)) {
                    return $c->create_simple_status_page(403, 'XSRF detected.');
                }
            }
            return;
        },
    );
}

この 403 Forbidden を回避するには、次のように jQuery.ajax()時に CSRF防止用のトークンを含めてpostするルールらしい。

$.ajax({
    url:   pulldownUrl,
    type: 'POST',
    data: {'XSRF-TOKEN': $.cookie('XSRF-TOKEN') }, //ココ.要jquery.cookie.js
    dataType: 'json'
}).done(function(getJson) {
    if(callback) callback(getJson);
});                    

2015-01-13追記 [TODO] cookie にあるXSRF-TOKEN を httponly にする必要は?

よく分かりませんでした。Amon2のsrcをgrepすると、XSRF-TOKENと別に csrf_token という値があることも気になりますが、その部分は、いつか気が向いたら