Skip to content

Commit 30d67a6

Browse files
author
Greg Bowler
authored
feature: multiple tokens exposed with comma separated meta content (#174)
closes #44
1 parent 7b02472 commit 30d67a6

File tree

2 files changed

+27
-11
lines changed

2 files changed

+27
-11
lines changed

src/HTMLDocumentProtector.php

+14-11
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,24 @@ public function protect(
5252
string $tokenSharing = self::ONE_TOKEN_PER_PAGE
5353
):string {
5454
$forms = $this->document->forms;
55+
$tokenArray = [];
5556

56-
if($forms->length > 0) {
57-
$token = $this->tokenStore->generateNewToken();
58-
$this->tokenStore->saveToken($token);
57+
$token = null;
5958

59+
if($forms->length > 0) {
6060
foreach($forms as $form) {
6161
$formMethod = $form->getAttribute("method");
6262
if(strtolower($formMethod) !== "post") {
6363
continue;
6464
}
6565

66+
if($tokenSharing === self::ONE_TOKEN_PER_FORM
67+
|| is_null($token)) {
68+
$token = $this->tokenStore->generateNewToken();
69+
$this->tokenStore->saveToken($token);
70+
array_push($tokenArray, $token);
71+
}
72+
6673
$csrfElement = $this->document->createElement(
6774
"input"
6875
);
@@ -82,16 +89,13 @@ public function protect(
8289
$csrfElement,
8390
$form->firstChild
8491
);
85-
86-
if($tokenSharing === self::ONE_TOKEN_PER_FORM) {
87-
$token = $this->tokenStore->generateNewToken();
88-
$this->tokenStore->saveToken($token);
89-
}
9092
}
9193
}
92-
else {
94+
95+
if(is_null($token)) {
9396
$token = $this->tokenStore->generateNewToken();
9497
$this->tokenStore->saveToken($token);
98+
array_push($tokenArray, $token);
9599
}
96100

97101
$meta = $this->document->querySelector(
@@ -123,8 +127,7 @@ public function protect(
123127
$head->appendChild($meta);
124128
}
125129

126-
$meta->setAttribute("content", $token);
127-
130+
$meta->setAttribute("content", implode(",", $tokenArray));
128131
return $token;
129132
}
130133

test/phpunit/HTMLDocumentProtectorTest.php

+13
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,19 @@ public function testProtect_metaTagAlreadyExists():void {
253253
self::assertNotEquals($originalValue, $metaTag->content);
254254
}
255255

256+
public function testProtect_metaTagMultipleForms():void {
257+
$document = new HTMLDocument(self::THREE_FORMS);
258+
$sut = new HTMLDocumentProtector($document, new ArrayTokenStore());
259+
$sut->protect(HTMLDocumentProtector::ONE_TOKEN_PER_FORM);
260+
261+
$nodeList = $document->querySelectorAll("head meta[name='" . HTMLDocumentProtector::TOKEN_NAME . "']");
262+
// There should still only be 1 meta tag...
263+
self::assertCount(1, $nodeList);
264+
// ... but the tag's content should have two values (one per POST form).
265+
$tokenArray = explode(",", $nodeList[0]->content);
266+
self::assertCount(2, $tokenArray);
267+
}
268+
256269
public function testProtect_differentTokenName() {
257270
$sut = new HTMLDocumentProtector(new HTMLDocument(self::HAS_META_ALREADY), new ArrayTokenStore());
258271
$tokenName = HTMLDocumentProtector::TOKEN_NAME;

0 commit comments

Comments
 (0)