Details
-
Bug
-
Resolution: Unresolved
-
High
-
None
-
3.3.6
-
Tested Ajax Call against Ibexa REST API with:
- jQuery v3.6.0
- Chrome v93.0
- Safari v14.0
-
Ibexa Experience
Description
Ajax Calls to REST API trigger preflight checks with OPTIONS header. This header validates allowed origin and methods. This preflight checks always fails against Ibexa REST API with HTTP:405
The allowed methods configured via nelmio_cors disappear in CorsListener during preflight check. The list of methods is empty.
config/packages/nelmio_cors.yaml configuration
nelmio_cors:
defaults:
origin_regex: false
allow_origin: ['https://<DOMAIN>']
allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
allow_headers: ['Content-Type', 'Authorization', 'Accept']
expose_headers: ['Link']
max_age: 3600
paths:
'^/api/ezp/v2/':
origin_regex: false
allow_credentials: true
allow_origin: ['https://<DOMAIN>']
allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
allow_headers: ['Content-Type', 'Authorization', 'Accept']
expose_headers: ['Link']
max_age: 3600
The returned $options from configResolver is empty for REST API calls in:
https://github.com/nelmio/NelmioCorsBundle/blob/master/EventListener/CorsListener.php#L57
This leads to return HTTP:405 as requested method is not allowed in:
https://github.com/nelmio/NelmioCorsBundle/blob/master/EventListener/CorsListener.php#L155
Example JavaScript code to trigger REST API via jQuery:{{}}
<html>
<head>
<meta charset="utf-8">
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
</head>
<body>
REST TEST
<script>
$( document ).ready(function() {
$.ajax({
url: "https://<DOMAIN>/api/ezp/v2/user/sessions",
type: "POST",
xhrFields: {
withCredentials: true
},
crossDomain: true,
headers: {
"Accept": "application/vnd.ez.api.Session+json",
"Content-Type": "application/vnd.ez.api.SessionInput+json"
},
contentType: "application/json",
dataType: 'json',
data: JSON.stringify({"SessionInput": {"login": "<login>","password": "<password>"),}}
success: function(result){
console.log(result);
{{ }}}
})
});
</script>
</body>
</html>