Skip to content
← Back to Functions
Code

Secure CSRF Token Manager

Creates and stores a scoped CSRF token with expiration and rotation support.

Function signature

ogCreateCsrfToken(scope, ttl_seconds = 1800, rotate = true)

Categories

  • Security

Parameters

scopeStable form/action scope name.ttl_secondsNumber of seconds before the token expires.rotateWhether this token should replace the prior scoped token.

Return value

Short public-safe status message.

  • scope
  • token
  • token_hash
  • created_at
  • expires_at
  • rotate

Compatibility

Existing function name and call order preserved; metadata signature corrected to source.

Minimum PHP version: 7.4

Security notes

Validate request method, identity, permissions, and caller-owned allowlists before use; keep secrets out of public output.

Code

<?php

/*
 * Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
 * Free for personal and internal use. Paid project use requires visible credit
 * to Jeffery L. Paris. Corporate use requires a paid license fee unless a
 * separate written license states otherwise.
 */

/**
 * Creates a scoped CSRF token record with expiration metadata.
 *
 * This function does not write into $_SESSION directly. It returns a token
 * record that the calling controller can store in the approved session key.
 *
 * @param string $scope Stable form/action scope name.
 * @param int $ttl_seconds Number of seconds before the token expires.
 * @param bool $rotate Whether this token should replace the prior scoped token.
 * @return array Structured result with token metadata.
 */
function ogCreateCsrfToken($scope, $ttl_seconds = 1800, $rotate = true) {
	$result = array(
		'success' => false,
		'message' => '',
		'data' => array()
	);

	$scope = trim((string)$scope);
	$ttl_seconds = (int)$ttl_seconds;

	if (empty($scope)) {
		$result['message'] = 'Missing CSRF scope.';
		return $result;
	}

	if (!preg_match('/^[a-zA-Z0-9_\-:.]+$/', $scope)) {
		$result['message'] = 'CSRF scope contains unsupported characters.';
		return $result;
	}

	if ($ttl_seconds < 60) {
		$ttl_seconds = 60;
	}

	if ($ttl_seconds > 86400) {
		$ttl_seconds = 86400;
	}

	$created_at = time();
	$token = bin2hex(random_bytes(32));
	$token_hash = hash('sha256', $token);

	$result['success'] = true;
	$result['message'] = 'CSRF token created.';
	$result['data'] = array(
		'scope' => $scope,
		'token' => $token,
		'token_hash' => $token_hash,
		'created_at' => $created_at,
		'expires_at' => $created_at + $ttl_seconds,
		'rotate' => (bool)$rotate
	);

	return $result;
}