Skip to content

Commit c902ac4

Browse files
committed
fix using csp nonce by passing it from the view to the default script tag and added explanations in the readme
1 parent 6efe10d commit c902ac4

File tree

4 files changed

+34
-32
lines changed

4 files changed

+34
-32
lines changed

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,29 @@ $factors['years'] = [365, 'dayz'];
439439

440440
More information on CarbonInterval's gotchas in [Constantin's blog post on chasingcode.dev](https://chasingcode.dev/blog/carbon-php-practical-examples/).
441441

442+
### Content Security Policy
443+
444+
This package supports CSP nonces for secure script loading. Pass your nonce to the @cookieconsentscripts directive:
445+
446+
```blade
447+
{{-- Basic usage with nonce --}}
448+
@cookieconsentscripts($yourNonce)
449+
450+
{{-- Example with Spatie Laravel CSP --}}
451+
@cookieconsentscripts(app('csp-nonce'))
452+
453+
{{-- Without CSP --}}
454+
@cookieconsentscripts
455+
```
456+
457+
How It Works
458+
459+
When you provide a nonce, it's added to the script tag:
460+
461+
```html
462+
<script src="/cookie-consent-script" nonce="your-nonce-here" defer></script>
463+
```
464+
442465
### Let your users change their mind
443466

444467
Users should be able to change their consent settings at any time. No worries, with this package it is quite simple to achieve: generate a button that will reset the user's cookies and show the consent modal again.

config/cookieconsent.php

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,6 @@
5555

5656
'policy' => null,
5757

58-
/*
59-
|--------------------------------------------------------------------------
60-
| CSP configuration
61-
|--------------------------------------------------------------------------
62-
|
63-
| Most cookie notices display a link to a dedicated page explaining
64-
| the extended cookies usage policy. If your application has such a page
65-
| you can add its route name here.
66-
|
67-
*/
68-
69-
'csp_enable' => env('CSP_ENABLE', false),
70-
7158
/* Google Analytics configuration
7259
|--------------------------------------------------------------------------
7360
|

src/CookiesManager.php

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,11 @@ protected function makeConsentCookie(): CookieComponent
168168
/**
169169
* Output all the scripts for current consent state.
170170
*/
171-
public function renderScripts(bool $withDefault = true): string
171+
public function renderScripts(bool $withDefault = true, ?string $nonce = null): string
172172
{
173173
$output = $this->shouldDisplayNotice()
174-
? $this->getNoticeScripts($withDefault)
175-
: $this->getConsentedScripts($withDefault);
174+
? $this->getNoticeScripts($withDefault, $nonce)
175+
: $this->getConsentedScripts($withDefault, $nonce);
176176

177177
if(strlen($output)) {
178178
$output = '<!-- Cookie Consent -->' . $output;
@@ -181,14 +181,14 @@ public function renderScripts(bool $withDefault = true): string
181181
return $output;
182182
}
183183

184-
public function getNoticeScripts(bool $withDefault): string
184+
public function getNoticeScripts(bool $withDefault, ?string $nonce = null): string
185185
{
186-
return $withDefault ? $this->getDefaultScriptTag() : '';
186+
return $withDefault ? $this->getDefaultScriptTag($nonce) : '';
187187
}
188188

189-
protected function getConsentedScripts(bool $withDefault): string
189+
protected function getConsentedScripts(bool $withDefault, ?string $nonce = null): string
190190
{
191-
$output = $this->getNoticeScripts($withDefault);
191+
$output = $this->getNoticeScripts($withDefault, $nonce);
192192

193193
foreach ($this->getConsentResponse()->getResponseScripts() ?? [] as $tag) {
194194
$output .= $tag;
@@ -197,23 +197,16 @@ protected function getConsentedScripts(bool $withDefault): string
197197
return $output;
198198
}
199199

200-
protected function getDefaultScriptTag(): string
200+
protected function getDefaultScriptTag(?string $nonce = null): string
201201
{
202-
$csp_enable = config('cookieconsent.csp_enable', false);
203-
204202
return '<script '
205203
. 'src="' . route('cookieconsent.script') . '?id='
206-
. md5(\filemtime(LCC_ROOT . '/dist/script.js')) . '" '
207-
. ($csp_enable ? 'nonce="' . $this->generateCspNonce() . '" ' : '')
204+
. md5(\filemtime(LCC_ROOT . '/dist/script.js')) . '" '
205+
. ($nonce ? 'nonce="' . $nonce . '" ' : '')
208206
. 'defer'
209207
. '></script>';
210208
}
211209

212-
protected function generateCspNonce(): string
213-
{
214-
return bin2hex(random_bytes(16));
215-
}
216-
217210
/**
218211
* Output the consent alert/modal for current consent state.
219212
*/

src/ServiceProvider.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,8 @@ public function boot()
6464
protected function registerBladeDirectives()
6565
{
6666
Blade::directive('cookieconsentscripts', function (string $expression) {
67-
return '<?php echo ' . Facades\Cookies::class . '::renderScripts(' . $expression . '); ?>';
67+
return '<?php echo ' . Facades\Cookies::class . '::renderScripts(!empty($expression) ? true, ' . $expression . ' : ""); ?>';
6868
});
69-
7069
Blade::directive('cookieconsentview', function (string $expression) {
7170
return '<?php echo ' . Facades\Cookies::class . '::renderView(); ?>';
7271
});

0 commit comments

Comments
 (0)