Skip to content

Commit 7a26818

Browse files
committed
Add some missing docs.
1 parent 60d6aad commit 7a26818

File tree

2 files changed

+173
-7
lines changed

2 files changed

+173
-7
lines changed

en/controllers/request-response.rst

Lines changed: 169 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,9 +1076,10 @@ will make the browser remove its local cookie::
10761076
Setting Cross Origin Request Headers (CORS)
10771077
-------------------------------------------
10781078

1079-
The ``cors()`` method is used to define `HTTP Access Control
1079+
The ``cors()`` method returns a ``CorsBuilder`` instance which provides a fluent
1080+
interface for defining `HTTP Access Control
10801081
<https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS>`__
1081-
related headers with a fluent interface::
1082+
related headers::
10821083

10831084
$this->response = $this->response->cors($this->request)
10841085
->allowOrigin(['*.cakephp.org'])
@@ -1095,11 +1096,173 @@ criteria are met:
10951096
#. The request has an ``Origin`` header.
10961097
#. The request's ``Origin`` value matches one of the allowed Origin values.
10971098

1098-
.. tip::
1099+
CorsBuilder Methods
1100+
~~~~~~~~~~~~~~~~~~~
10991101

1100-
CakePHP has no built-in CORS middleware because dealing with CORS requests
1101-
is very application specific. We recommend you build your own ``CORSMiddleware``
1102-
if you need one and adjust the response object as desired.
1102+
.. php:class:: CorsBuilder
1103+
1104+
The ``CorsBuilder`` provides the following methods for configuring CORS:
1105+
1106+
.. php:method:: allowOrigin(array|string $domains)
1107+
1108+
Set the list of allowed domains. You can use wildcards ``*.example.com`` to
1109+
accept subdomains, or ``*`` to allow all domains::
1110+
1111+
// Allow a specific domain
1112+
->allowOrigin('https://example.com')
1113+
1114+
// Allow multiple domains
1115+
->allowOrigin(['https://example.com', 'https://app.example.com'])
1116+
1117+
// Allow all subdomains
1118+
->allowOrigin(['*.example.com'])
1119+
1120+
// Allow all origins (use with caution!)
1121+
->allowOrigin('*')
1122+
1123+
.. php:method:: allowMethods(array $methods)
1124+
1125+
Set the list of allowed HTTP methods::
1126+
1127+
->allowMethods(['GET', 'POST', 'PUT', 'DELETE'])
1128+
1129+
.. php:method:: allowHeaders(array $headers)
1130+
1131+
Define which headers can be sent in CORS requests::
1132+
1133+
->allowHeaders(['X-CSRF-Token', 'Content-Type', 'Authorization'])
1134+
1135+
.. php:method:: allowCredentials()
1136+
1137+
Enable cookies to be sent in CORS requests. This sets the
1138+
``Access-Control-Allow-Credentials`` header to ``true``::
1139+
1140+
->allowCredentials()
1141+
1142+
.. php:method:: exposeHeaders(array $headers)
1143+
1144+
Define which headers the client library/browser can expose to scripting::
1145+
1146+
->exposeHeaders(['X-Total-Count', 'Link'])
1147+
1148+
.. php:method:: maxAge(string|int $age)
1149+
1150+
Define how long preflight OPTIONS requests are valid for (in seconds)::
1151+
1152+
->maxAge(3600) // Cache preflight for 1 hour
1153+
1154+
.. php:method:: build()
1155+
1156+
Apply the configured headers to the response and return it. This must be
1157+
called to actually apply the CORS headers::
1158+
1159+
$response = $corsBuilder->build();
1160+
1161+
Practical CORS Examples
1162+
~~~~~~~~~~~~~~~~~~~~~~~
1163+
1164+
Here are some common CORS configurations:
1165+
1166+
**API accepting requests from a SPA frontend**::
1167+
1168+
// In your controller
1169+
public function beforeFilter(EventInterface $event)
1170+
{
1171+
parent::beforeFilter($event);
1172+
1173+
if ($this->request->is('options')) {
1174+
// Handle preflight requests
1175+
$this->response = $this->response->cors($this->request)
1176+
->allowOrigin(['https://app.example.com'])
1177+
->allowMethods(['GET', 'POST', 'PUT', 'DELETE'])
1178+
->allowHeaders(['Content-Type', 'Authorization'])
1179+
->allowCredentials()
1180+
->maxAge(86400)
1181+
->build();
1182+
1183+
return $this->response;
1184+
}
1185+
}
1186+
1187+
public function index()
1188+
{
1189+
// Apply CORS to regular requests
1190+
$this->response = $this->response->cors($this->request)
1191+
->allowOrigin(['https://app.example.com'])
1192+
->allowCredentials()
1193+
->build();
1194+
1195+
// Your regular controller logic...
1196+
}
1197+
1198+
**Public API with relaxed CORS**::
1199+
1200+
$this->response = $this->response->cors($this->request)
1201+
->allowOrigin('*')
1202+
->allowMethods(['GET'])
1203+
->exposeHeaders(['X-Total-Count', 'X-Page'])
1204+
->maxAge(3600)
1205+
->build();
1206+
1207+
Creating CORS Middleware
1208+
~~~~~~~~~~~~~~~~~~~~~~~~
1209+
1210+
For consistent CORS handling across your application, create a middleware::
1211+
1212+
// src/Middleware/CorsMiddleware.php
1213+
namespace App\Middleware;
1214+
1215+
use Psr\Http\Message\ResponseInterface;
1216+
use Psr\Http\Message\ServerRequestInterface;
1217+
use Psr\Http\Server\MiddlewareInterface;
1218+
use Psr\Http\Server\RequestHandlerInterface;
1219+
1220+
class CorsMiddleware implements MiddlewareInterface
1221+
{
1222+
public function process(
1223+
ServerRequestInterface $request,
1224+
RequestHandlerInterface $handler
1225+
): ResponseInterface {
1226+
// Handle preflight requests
1227+
if ($request->getMethod() === 'OPTIONS') {
1228+
$response = new \Cake\Http\Response();
1229+
$response = $response->cors($request)
1230+
->allowOrigin(['*.myapp.com'])
1231+
->allowMethods(['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'])
1232+
->allowHeaders(['Content-Type', 'Authorization'])
1233+
->allowCredentials()
1234+
->maxAge(3600)
1235+
->build();
1236+
1237+
return $response;
1238+
}
1239+
1240+
$response = $handler->handle($request);
1241+
1242+
// Add CORS headers to regular requests
1243+
return $response->cors($request)
1244+
->allowOrigin(['*.myapp.com'])
1245+
->allowCredentials()
1246+
->build();
1247+
}
1248+
}
1249+
1250+
Then add it to your application middleware stack in ``src/Application.php``::
1251+
1252+
public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
1253+
{
1254+
$middlewareQueue
1255+
// Add CORS middleware early in the stack
1256+
->add(new \App\Middleware\CorsMiddleware())
1257+
// ... other middleware
1258+
->add(new ErrorHandlerMiddleware(Configure::read('Error')))
1259+
->add(new AssetMiddleware([
1260+
'cacheTime' => Configure::read('Asset.cacheTime'),
1261+
]))
1262+
->add(new RoutingMiddleware($this));
1263+
1264+
return $middlewareQueue;
1265+
}
11031266

11041267
Running logic after the Response has been sent
11051268
----------------------------------------------

en/orm/database-basics.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,10 @@ uuid
352352
generate a ``CHAR(36)`` field.
353353
binaryuuid
354354
Maps to the UUID type if the database provides one, otherwise this will
355-
generate a ``BINARY(16)`` column
355+
generate a ``BINARY(16)`` column. Binary UUIDs provide more efficient storage
356+
compared to string UUIDs by storing the UUID as 16 bytes of binary data rather
357+
than a 36-character string. This type automatically handles conversion between
358+
string UUID format (with dashes) and binary format.
356359
nativeuuid
357360
Maps to the UUID type in MySQL with MariaDb. In all other databases,
358361
``nativeuuid`` is an alias for ``uuid``.

0 commit comments

Comments
 (0)