CORS and CORS in SCC
1. What Is CORS?
CORS stands for Cross-Origin Resource Sharing. It is a browser security mechanism that controls whether a web page from one origin can access resources from another origin.
For SAP Commerce developers, CORS is particularly important when a storefront such as Spartacus makes HTTP requests to SAP Commerce OCC APIs.
First, understand what an origin is
An origin consists of three components:
scheme + hostname + port
For example:
| URL | Origin |
|---|---|
https://localhost:9002 | https://localhost:9002 |
https://localhost:4200 | https://localhost:4200 |
http://localhost:9002 | http://localhost:9002 |
https://example.com | https://example.com |
These are different origins because their schemes, hostnames, or ports differ.
Even though https://localhost:9002 and https://localhost:4200 use the same hostname, their ports differ, so they are different origins.
Important: CORS is primarily enforced by web browsers. It determines whether JavaScript running on one origin is allowed to read a response from another origin. It is not a replacement for authentication or authorization, and it does not generally prevent non-browser clients such as curl from sending requests.
2. Understanding Your SAP Commerce Configuration
You provided these properties:
corsfilter.default.allowedOrigins=https://localhost:9002
corsfilter.default.allowedMethods=GET
Let’s examine each property.
A. corsfilter.default.allowedOrigins
corsfilter.default.allowedOrigins=https://localhost:9002
This specifies which origin is allowed to access resources covered by the corresponding SAP Commerce CORS configuration.
Suppose your environment looks like this:
Spartacus Storefront
https://localhost:9002
|
| HTTP GET request
▼
SAP Commerce OCC
https://localhost:9002/occ/v2/electronics/products
In this example, both the storefront and OCC use the same origin. CORS is not required for that request because it is same-origin.
Now suppose the storefront runs on port 4200 instead:
Spartacus Storefront
https://localhost:4200
|
| HTTP GET request
▼
SAP Commerce OCC
https://localhost:9002/occ/v2/electronics/products
The browser sees two different origins:
- Request origin:
https://localhost:4200 - Target origin:
https://localhost:9002
Your current configuration allows https://localhost:9002, not https://localhost:4200.
Therefore, if this CORS configuration applies to the OCC endpoint, the storefront origin https://localhost:4200 would not be allowed to read the response.
To permit that storefront origin, you would configure:
corsfilter.default.allowedOrigins=https://localhost:4200
The exact configuration needed depends on which origin your storefront uses and which CORS configuration applies to the endpoint.
B. corsfilter.default.allowedMethods
corsfilter.default.allowedMethods=GET
This specifies the HTTP methods allowed by the corresponding CORS configuration.
Your configuration allows GET requests.
Common HTTP methods include:
| HTTP method | Purpose | Example in SAP Commerce |
|---|---|---|
GET | Retrieve data | Get product details |
POST | Create a resource or submit data | Add an item to a cart |
PUT | Replace or update a resource | Update a resource |
PATCH | Partially update a resource | Update selected customer fields |
DELETE | Delete a resource | Remove a resource |
Suppose your Spartacus storefront needs to retrieve products and add products to a cart.
If the storefront makes these requests:
GET /occ/v2/electronics/products
POST /occ/v2/electronics/users/current/carts
With your current configuration:
corsfilter.default.allowedMethods=GET
The browser may allow the cross-origin GET request, assuming the origin and other relevant CORS requirements are satisfied.
However, the cross-origin POST request will not be permitted by this CORS policy.
To allow both methods, you could configure:
corsfilter.default.allowedMethods=GET,POST
Note: Allowing a method through CORS does not guarantee that the request will succeed. The endpoint must support the method, and authentication, authorization, CSRF protection, and other applicable security controls must still be satisfied.
3. How Does CORS Work Internally?
Consider a Spartacus storefront calling SAP Commerce OCC.
Scenario A: A simple GET request
The storefront runs at:
https://localhost:4200
It requests:
https://localhost:9002/occ/v2/electronics/products
Step 1 — The browser sends a request
The browser includes an Origin header:
GET /occ/v2/electronics/products HTTP/1.1
Host: localhost:9002
Origin: https://localhost:4200
Step 2 — SAP Commerce processes the request
The server processes the request and its CORS filter evaluates the applicable CORS configuration.
Step 3 — The server returns a CORS response header
If the origin is permitted, the response might contain:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://localhost:4200
Content-Type: application/json
Step 4 — The browser checks the response
The browser checks whether the response permits the requesting origin.
If the CORS checks pass, JavaScript can read the response.
If the server does not return the required CORS headers, the browser blocks JavaScript from reading the cross-origin response.
An important distinction: a CORS error does not necessarily mean the server never received or processed the request. For some requests, the server may process the request even though the browser subsequently blocks JavaScript from accessing the response.
Scenario B: A preflight request
Some cross-origin requests trigger a preliminary browser request called a preflight request.
For example, your storefront sends a POST request with an Authorization header and a JSON body.
The browser may first send:
OPTIONS /occ/v2/electronics/users/current/carts HTTP/1.1
Host: localhost:9002
Origin: https://localhost:4200
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization,content-type
This asks the server whether the browser may send the intended request.
If the request is permitted, the server could respond:
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://localhost:4200
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: authorization, content-type
The browser can then proceed with the actual POST request.
If the preflight fails, the browser will not send the actual request.
Why is this relevant to your configuration?
If your application allows only GET, a cross-origin POST request will not be permitted by that policy. The preflight request may also fail if the server does not allow the requested method or headers.
Not every GET request triggers a preflight. Simple cross-origin requests can be sent without one.
4. What Other CORS Properties Might You Need in SAP Commerce?
Depending on your SAP Commerce version, the applicable CORS configuration, and your storefront’s requests, you may encounter properties such as these:
corsfilter.default.allowedOrigins=https://localhost:4200
corsfilter.default.allowedMethods=GET,POST,PUT,PATCH,DELETE,OPTIONS
corsfilter.default.allowedHeaders=origin,content-type,accept,authorization
corsfilter.default.exposedHeaders=x-total-count
corsfilter.default.allowCredentials=true
These are illustrative settings, not a recommendation to enable every method or header in production. Verify the supported properties and exact syntax for your SAP Commerce version and the particular CORS configuration you are using.
| Property | Purpose |
|---|---|
allowedOrigins | Specifies permitted requesting origins. |
allowedMethods | Specifies permitted cross-origin HTTP methods. |
allowedHeaders | Specifies which request headers the browser may send for a cross-origin request. |
exposedHeaders | Specifies which response headers JavaScript may read. |
allowCredentials | Controls whether cross-origin requests may use browser credentials, subject to the browser’s CORS rules. |
A few security considerations
1. Avoid allowing every origin unnecessarily.
For example, allowing arbitrary origins can expose responses to unintended websites, particularly when sensitive data is involved.
2. Be careful with credentials.
If cross-origin cookies or other browser credentials are required, the server must return an explicit permitted origin. A wildcard origin (*) cannot be used with credentialed CORS responses.
3. CORS is not authentication.
Allowing https://localhost:4200 does not prove that a request comes from an authenticated or authorized user. Other clients can send HTTP requests without browser CORS enforcement.
4. Do not confuse CORS with CSRF protection.
CORS controls browser access to cross-origin responses and, for preflighted requests, whether the browser may proceed with the actual request. CSRF protection addresses a different risk: unwanted actions performed using a user’s existing authenticated session.
5. How Should You Configure CORS for Your SAP Commerce Development Environment?
First, identify your actual storefront and OCC origins.
For example:
Spartacus:
https://localhost:4200
SAP Commerce:
https://localhost:9002
If your Spartacus storefront calls OCC directly from the browser, you may need a CORS configuration that permits the storefront’s origin.
An illustrative configuration might be:
corsfilter.default.allowedOrigins=https://localhost:4200
corsfilter.default.allowedMethods=GET,POST,PUT,PATCH,DELETE,OPTIONS
corsfilter.default.allowedHeaders=origin,content-type,accept,authorization
The required settings depend on the requests your storefront makes. Also verify that this default configuration is actually associated with the OCC endpoints you are calling; changing a CORS property does not necessarily affect every endpoint.
If your storefront and OCC use the same origin, browser CORS configuration is generally unnecessary for those requests.
Summary
Your original configuration:
corsfilter.default.allowedOrigins=https://localhost:9002
corsfilter.default.allowedMethods=GET
means:
allowedOrigins: Permits the specified origin to access responses governed by this CORS configuration.allowedMethods: Permits cross-origin requests usingGET, subject to the remaining CORS requirements.- Important: If your Spartacus storefront runs at
https://localhost:4200, that origin is different fromhttps://localhost:9002and is not permitted by the origin setting you showed.
One question to help diagnose your actual setup: Is your Spartacus storefront running on https://localhost:4200, https://localhost:9002, or another port? That determines whether your current allowedOrigins setting is appropriate.
