Skip to content

Commit 69038f6

Browse files
authored
Merge pull request #4193 from paulbalandan/alternative-cookie-implementation
Abstraction for cookies and cookie collections
2 parents 3ea8cdf + 6367766 commit 69038f6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+3742
-1042
lines changed

app/Config/App.php

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Config;
44

55
use CodeIgniter\Config\BaseConfig;
6+
use DateTimeInterface;
67

78
class App extends BaseConfig
89
{
@@ -279,14 +280,14 @@ class App extends BaseConfig
279280

280281
/**
281282
* --------------------------------------------------------------------------
282-
* Cookie HTTP Only
283+
* Cookie HttpOnly
283284
* --------------------------------------------------------------------------
284285
*
285286
* Cookie will only be accessible via HTTP(S) (no JavaScript).
286287
*
287288
* @var boolean
288289
*/
289-
public $cookieHTTPOnly = false;
290+
public $cookieHTTPOnly = true;
290291

291292
/**
292293
* --------------------------------------------------------------------------
@@ -299,14 +300,50 @@ class App extends BaseConfig
299300
* - Strict
300301
* - ''
301302
*
303+
* Alternatively, you can use the constant names:
304+
* - `Cookie::SAMESITE_NONE`
305+
* - `Cookie::SAMESITE_LAX`
306+
* - `Cookie::SAMESITE_STRICT`
307+
*
302308
* Defaults to `Lax` for compatibility with modern browsers. Setting `''`
303-
* (empty string) means no SameSite attribute will be set on cookies. If
304-
* set to `None`, `$cookieSecure` must also be set.
309+
* (empty string) means default SameSite attribute set by browsers (`Lax`)
310+
* will be set on cookies. If set to `None`, `$cookieSecure` must also be set.
305311
*
306-
* @var string 'Lax'|'None'|'Strict'
312+
* @var string
307313
*/
308314
public $cookieSameSite = 'Lax';
309315

316+
/**
317+
* --------------------------------------------------------------------------
318+
* Cookie Raw
319+
* --------------------------------------------------------------------------
320+
*
321+
* This flag allows setting a "raw" cookie, i.e., its name and value are
322+
* not URL encoded using `rawurlencode()`.
323+
*
324+
* If this is set to `true`, cookie names should be compliant of RFC 2616's
325+
* list of allowed characters.
326+
*
327+
* @var boolean
328+
*
329+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#attributes
330+
* @see https://tools.ietf.org/html/rfc2616#section-2.2
331+
*/
332+
public $cookieRaw = false;
333+
334+
/**
335+
* --------------------------------------------------------------------------
336+
* Cookie Expires Timestamp
337+
* --------------------------------------------------------------------------
338+
*
339+
* Default expires timestamp for cookies. Setting this to `0` will mean the
340+
* cookie will not have the `Expires` attribute and will behave as a session
341+
* cookie.
342+
*
343+
* @var DateTimeInterface|integer|string
344+
*/
345+
public $cookieExpires = 0;
346+
310347
/**
311348
* --------------------------------------------------------------------------
312349
* Reverse Proxy IPs

app/Config/Security.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,12 @@ class Security extends BaseConfig
8484
* Allowed values are: None - Lax - Strict - ''.
8585
*
8686
* Defaults to `Lax` as recommended in this link:
87+
*
8788
* @see https://portswigger.net/web-security/csrf/samesite-cookies
8889
*
89-
* @var string 'Lax'|'None'|'Strict'
90+
* @var string
91+
*
92+
* @deprecated
9093
*/
9194
public $samesite = 'Lax';
9295
}

system/Common.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
use CodeIgniter\Database\ConnectionInterface;
1616
use CodeIgniter\Debug\Timer;
1717
use CodeIgniter\Files\Exceptions\FileNotFoundException;
18+
use CodeIgniter\HTTP\Cookie\Cookie;
19+
use CodeIgniter\HTTP\Cookie\CookieStore;
20+
use CodeIgniter\HTTP\Exceptions\CookieException;
1821
use CodeIgniter\HTTP\Exceptions\HTTPException;
1922
use CodeIgniter\HTTP\RedirectResponse;
2023
use CodeIgniter\HTTP\RequestInterface;
@@ -226,6 +229,46 @@ function config(string $name, bool $getShared = true)
226229
}
227230
}
228231

232+
if (! function_exists('cookie'))
233+
{
234+
/**
235+
* Simpler way to create a new Cookie instance.
236+
*
237+
* @param string $name Name of the cookie
238+
* @param string $value Value of the cookie
239+
* @param array $options Array of options to be passed to the cookie
240+
*
241+
* @throws CookieException
242+
*
243+
* @return Cookie
244+
*/
245+
function cookie(string $name, string $value = '', array $options = []): Cookie
246+
{
247+
return Cookie::create($name, $value, $options);
248+
}
249+
}
250+
251+
if (! function_exists('cookies'))
252+
{
253+
/**
254+
* Fetches the global `CookieStore` instance held by `Response`.
255+
*
256+
* @param Cookie[] $cookies If `getGlobal` is false, this is passed to CookieStore's constructor
257+
* @param boolean $getGlobal If false, creates a new instance of CookieStore
258+
*
259+
* @return CookieStore
260+
*/
261+
function cookies(array $cookies = [], bool $getGlobal = true): CookieStore
262+
{
263+
if ($getGlobal)
264+
{
265+
return Services::response()->getCookieStore();
266+
}
267+
268+
return new CookieStore($cookies);
269+
}
270+
}
271+
229272
if (! function_exists('csrf_token'))
230273
{
231274
/**

system/Config/Services.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ public static function security(App $config = null, bool $getShared = true)
677677
return static::getSharedInstance('security', $config);
678678
}
679679

680-
$config = $config ?? config('Security') ?? config('App');
680+
$config = $config ?? config('App');
681681

682682
return new Security($config);
683683
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the CodeIgniter 4 framework.
5+
*
6+
* (c) CodeIgniter Foundation <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace CodeIgniter\HTTP\Cookie;
13+
14+
use DateTimeInterface;
15+
16+
/**
17+
* Interface for a fresh Cookie instance with selected attribute(s)
18+
* only changed from the original instance.
19+
*/
20+
interface CloneableCookieInterface extends CookieInterface
21+
{
22+
/**
23+
* Creates a new Cookie with URL encoding option updated.
24+
*
25+
* @param boolean $raw
26+
*
27+
* @return static
28+
*/
29+
public function withRaw(bool $raw = true);
30+
31+
/**
32+
* Creates a new Cookie with a new cookie prefix.
33+
*
34+
* @param string $prefix
35+
*
36+
* @return static
37+
*/
38+
public function withPrefix(string $prefix = '');
39+
40+
/**
41+
* Creates a new Cookie with a new name.
42+
*
43+
* @param string $name
44+
*
45+
* @return static
46+
*/
47+
public function withName(string $name);
48+
49+
/**
50+
* Creates a new Cookie with new value.
51+
*
52+
* @param string $value
53+
*
54+
* @return static
55+
*/
56+
public function withValue(string $value);
57+
58+
/**
59+
* Creates a new Cookie with a new cookie expires time.
60+
*
61+
* @param DateTimeInterface|integer|string $expires
62+
*
63+
* @return static
64+
*/
65+
public function withExpiresAt($expires = 0);
66+
67+
/**
68+
* Creates a new Cookie that will expire the cookie from the browser.
69+
*
70+
* @return static
71+
*/
72+
public function withExpired();
73+
74+
/**
75+
* Creates a new Cookie that will virtually never expire from the browser.
76+
*
77+
* @return static
78+
*/
79+
public function withNeverExpiring();
80+
81+
/**
82+
* Creates a new Cookie with a new domain the cookie is available.
83+
*
84+
* @param string|null $domain
85+
*
86+
* @return static
87+
*/
88+
public function withDomain(?string $domain);
89+
90+
/**
91+
* Creates a new Cookie with a new path on the server the cookie is available.
92+
*
93+
* @param string|null $path
94+
*
95+
* @return static
96+
*/
97+
public function withPath(?string $path);
98+
99+
/**
100+
* Creates a new Cookie with a new "Secure" attribute.
101+
*
102+
* @param boolean $secure
103+
*
104+
* @return static
105+
*/
106+
public function withSecure(bool $secure = true);
107+
108+
/**
109+
* Creates a new Cookie with a new "HttpOnly" attribute
110+
*
111+
* @param boolean $httpOnly
112+
*
113+
* @return static
114+
*/
115+
public function withHttpOnly(bool $httpOnly = true);
116+
117+
/**
118+
* Creates a new Cookie with a new "SameSite" attribute.
119+
*
120+
* @param string $sameSite
121+
*
122+
* @return static
123+
*/
124+
public function withSameSite(string $sameSite);
125+
}

0 commit comments

Comments
 (0)