Mojoliciousでは内部実装可能
なんかtokenが同じ値なのでなんかおかしいかも…
サンプル
コントローラーのモジュール
package Sample::Web::Test1; use Mojo::Base 'Mojolicious::Controller'; use Mojolicious::Validator; use Mojolicious::Validator::Validation; # This action will render a template sub index { my $self = shift; # template変数を設定 #$self->stash->{msg} = "index"; $self->app->log->debug("index"); # template配下のtest1.aaa.html.ep $self->render(); } sub post { my $self = shift; # template変数を設定 #$self->stash->{msg} = "index"; # undefを設定してクリア $self->session->{csrf_token} = undef; $self->app->log->debug("new"); #$self->app->log->debug($self->session->{csrf_token}); if($self->session->{errors}){ $self->app->log->debug("error !!!"); $self->stash->{errors} = $self->session->{errors}; }else{ $self->stash->{errors} = undef; } $self->session->{errors} = undef; # template配下のtest1.aaa.html.ep $self->render('test1/post'); } sub conf { my $self = shift; my $validation = $self->validation; my $messages; if ($validation->csrf_protect->has_error('csrf_token') ) { return $self->render_not_found(); } if ($validation->required('title')->has_error('title') ) { push @$messages, 'title error !'; } if ($validation->required('body')->has_error('body') ) { push @$messages, 'body error !'; } my $cnt = scalar(@$messages); if($cnt > 0){ $self->session->{errors} = $messages; $self->redirect_to('/test1/new'); } # template変数を設定 #$self->stash->{msg} = "index"; $self->app->log->debug("conf"); $self->app->log->debug($self->param('title')); $self->app->log->debug($self->param('body')); $self->stash->{title} = $self->param('title'); $self->stash->{body} = $self->param('body'); # template配下のtest1.aaa.html.ep $self->render(); } sub create { my $self = shift; $self->redirect_to('/test1'); } 1;
※「$self->session->{csrf_token} = undef;」を設定することで毎回tokenの値を振り直し
※バリデータのモジュールでチェックなどを行う
CSRFは失敗時はエラー処理を実施するけど、入力データ不備の場合は前の画面へ戻す
テンプレート
% layout 'default'; % title 'Welcome'; % if ($errors) { <b>Error!</b> <ul> % for my $error (@$errors) { <li><%= $error %></li> % } </ul> % } <h1>入力してpostする画面</h1> <form action="./conf" method="post"> <input type="hidden" name="csrf_token" value="<%= csrf_token %>" /> <form role="form"> <div class="form-group"> <label for="title">タイトル</label> <input type="text" class="form-control" id="title" name="title" placeholder="タイトル"> </div> <div class="form-group"> <label for="body">Password</label> <input type="text" class="form-control" id="body" name="body" placeholder="本文"> </div> <button type="submit" class="btn btn-default">確認する</button> </form> </form>
※csrf_tokenというヘルパーが存在するのでそれを使用してtokenを設定する
所感
チェックするのをコントローラーでやらずにモデルとかでやったりといろいろ工夫することを追加して対応してみる必要があります。基本的な部分を少しずつうめていって対応して行くようにする