##はじめに
php(今回フレームワークは使用していない)でフォームを作成したときに、CSRF対策(セキュリティ対策)でセッションを使用した。フォームは「ユーザ入力ページ」「入力内容確認ページ」「送信完了ページの3つ」。フォームの送信が入るたびにページ遷移が入るようにしたが、ページ遷移と同時に設定したセッションの値が切れてしまったので、対策したことを備忘録として残します。
作成したトークンと、そのトークンをセッション変数に代入してページ遷移後に同じ値であれば、ページを表示するというよくあるやり方。
##結論
セッションに設定した変数は <?php の直後に書く。
##対策したこと
####ディレクトリ構成
root/
├index.php
├form-user-input.php
├form-confirm.php
├form-compleate.php
└parts
└header.php
index.phpにそれぞれ入力、確認、送信完了ページをincludeして表示させるような構成です。
まず下記は、form-user-input.phpでフォームを入力してpost送信した時に、ページ遷移後、セッションが切れてしまったコードです。ヘッダーは共通のものを使用していたので、一番上に読み込んでいました。
<?php
include('./parts/header.php'); //共通のヘッダー読み込み
session_start(); //セッションスタート
$token = 'random_char'; //トークン生成、本番ではランダムな文字列を入れてます
$_SESSION['token'] = $token; //$_SESSIONにトークンを代入
include('form-user-input.php');
//この下にフォームが送られた時の処理や、ファイル読み込みの処理を続けて書く
form-user-input.phpからform-confirm.phpに遷移すると、$_SESSIONがNULLになっていました。原因がわからず悩んだ、、、ファイルを読み込む際には、session_start()やセッション変数を書いた後に書くとうまくいきました。
<?php
session_start(); //セッションスタート
$token = 'random_char'; //トークン生成、本番ではランダムな文字列を入れてます
$_SESSION['token'] = $csrf_token; //$_SESSIONにトークンを代入
include('./parts/header.php'); //共通のヘッダー読み込み
include('form-user-input.php');
//この下にフォームが送られた時の処理や、ファイル読み込みの処理を続けて書く
これでページ遷移後にも$_SESSIONの値はNULLではなく、生成したトークンと同じ値が入っていました。
##おわりに
今回はページ遷移後にセッションが切れてしまう問題の解決方法を書きました。
セッションを用いたCSRF対策のコードの書き方を近いうちに記事にしようと思います。
また、本記事はあくまで僕が試してうまくいった一例なので、もっと他に効率いい方法があるかも、、
セッションについて詳しい方、ぜひコメント等で教えてくださいmm
p.s
フォーム作成はLaravel使うとセキュリティ対策の面でも多少書きやすくなるので、フレームワークおすすめです。