title: CSRF session token
body: <p>I'm trying to implement a simple CSRF protection on a form, but I can't get it right. If someone can point out what I'm doing wrong, I would appreciate it. </p>
  
  <p>The error: Every time I submit the form, I get "Invalid Submission2" because the token changes (after the form is submitted), since is being generated on the same page?</p>
  
  <p>Edit -- I forgot to mention, another file (config.php) already has session_start(). </p>
  
  <pre><code>&lt;?php
  class Module_Post extends Base_Module {
  
      public function start()
      {
          requireLogin();
  
          if (isset($_GET['act'])) {
              switch($_GET['act']) {
                  case 'text':
                      $this-&gt;text();
                      break;
                  case 'image':
                      $this-&gt;image();
                      break;
                  default:
                      $this-&gt;text();
                      break;
              }
          } else {
              $this-&gt;text();
          }
      }
  
      private function text()
      {
  
          // Generate random unique token to prevent cross-site request forgery (CSRF).
          if(empty($_SESSION['form_token'])) 
          {
              $form_token = md5(uniqid(rand(), TRUE));
              $_SESSION['form_token'] = $form_token;
          }
  
          if(isset($_POST['submit'])) 
          {
              // Clean the content from cross-site scripting (xss)
              $content = trim($_POST['content']);
              $content = Xss::clean($content);
  
              // Validate that the form token
              if(!isset($_POST['form_token'], $_SESSION['form_token'])) {
                  $err = 'Invalid Submission';
              } elseif ($_POST['form_token'] != $_SESSION['form_token']) {
                  $err = 'Invalid Submission2';
              } elseif (strlen($content) &lt; 10) {
                  $err = 'Your content contains too few characters.';
              }
  
              if(isset($err)) {
                  unset( $_SESSION['form_token']);
                  $this-&gt;setMessage($err, 'FAIL');
                  header('Location: index.php?mod=post');
                  exit;
              }
  
  
              // Insert database data here, then redirect
  
              $this-&gt;setMessage('Your post was published successfully.', 'GOOD');
              header('Location: index.php');
              exit;
          }
  
          $this-&gt;tpl-&gt;assign('form_token', $form_token);
          $this-&gt;tpl-&gt;display('new/text.tpl');
      }
  
  }
  ?&gt;
  </code></pre>
  
  <p>The HTML (text.tpl file) </p>
  
  <pre><code>&lt;form method='post' enctype='multipart/form-data' action='#'&gt;
    &lt;fieldset&gt;
      &lt;textarea rows="8" id="new_post" name="content" class="input-block-level"&gt;&lt;/textarea&gt;
      &lt;input type="hidden" name="form_token" value="{$form_token}" /&gt;
      &lt;button type="submit" name="submit" class="btn btn-info pull-left"&gt;Create Post&lt;/button&gt;
    &lt;/fieldset&gt;
  &lt;/form&gt;
  </code></pre>