Skip to content

Verifying requests

Greg Bowler edited this page Apr 22, 2026 · 1 revision

Once a token has been inserted into the page, the next step is to verify it when the browser submits the form.

The verify() method

The main entry point is TokenStore::verify():

$tokenStore->verify($_POST);

verify() expects either:

  • an array of submitted values
  • an object with an asArray() method

That second form exists so the package can work with object-based request input as well as plain PHP arrays.

What verify() checks

When verify() receives non-empty request data, it checks for a field named csrf-token.

The method then:

  1. throws CsrfTokenMissingException if the field is not present
  2. calls verifyToken() on the submitted value
  3. calls consumeToken() if the token is valid

That final step is important: tokens are single-use. A successful verification spends the token immediately.

Empty request bodies

If the submitted data is empty, verify() returns without throwing an exception:

$tokenStore->verify([]);

This allows the same code path to be called safely before deciding whether the request actually contains form input.

A common verification pattern

use GT\Csrf\Exception\CsrfException;

if($_SERVER["REQUEST_METHOD"] === "POST") {
	try {
		$tokenStore->verify($_POST);
	}
	catch(CsrfException $exception) {
		http_response_code(403);
		exit("Invalid CSRF token");
	}
}

This works because all package-specific CSRF exceptions inherit from CsrfException.

Verifying object-based input

If your request input is wrapped in an object, verify() will accept that too as long as it provides asArray():

$tokenStore->verify($postObject);

The object does not need to implement a formal interface here. The method simply checks whether asArray() can be called.

Repeated submissions

Because a valid token is spent immediately after verification, submitting the same form twice will fail on the second attempt with CsrfTokenSpentException.

This matters when:

  • a user double-clicks the submit button
  • JavaScript retries a request using an old token
  • one page submits several background requests using the same token

In those cases, render or fetch a fresh page so the client receives new tokens.

Reading the token name

The field and meta tag name are defined as:

GT\Csrf\HTMLDocumentProtector::TOKEN_NAME

The current value is csrf-token.


Next, move on to Exceptions to see what each failure mode means and how to handle it.

Clone this wiki locally