Cross-Origin Resource Sharing (CORS)
Recently I have had a lot of people asking me about why they are getting an error complaining of a unable to connect or a -1 connection error.
This is often a Cross-Origin Resource Sharing (CORS) error. The role of CORS is to tell the client/browser what is allowed or not allowed on the HTTPs endpoint, it does not do enforcement itself. A client/browser makes an HTTP Options request to the endpoint to find out what it is allowed to do. Providing those headers (below) have been injected into the response this tells the client/browser what it is entitled to do. CORS is not there to add extra protection, it is there rather to provide extra information to the client/browser. Some http libraries such as NodeJS’s request do include an option call prior to the requested call to help enforce this, but it is a client-application decision. If the CORS headers stop the requested operation then a -1 is showing in the error.
This could be due to the operation returning a 404, or an invalid VERB is called.
If you are using API connect and you would like to build a custom set of CORS rules you can do this very easily. Firstly untick the core tick box to stop the default settings being applied. Add the following headers to the response of the options call.
message.headers.Access-Control-Allow-Method
with a list of allowed verbsmessage.headers.Access-Control-Allow-Origin
with a list of allowed origin requests
A full example is available below
swagger: '2.0'
info:
version: 1.0.0
title: IpLookUp
x-ibm-name: iplookup
description: API to show your external IP address
basePath: /iplookup
x-ibm-configuration:
properties:
target-url:
value: http://httpbin.org/ip
description: URL of the proxy policy
encoded: false
cors:
enabled: false
gateway: datapower-api-gateway
type: rest
phase: realized
enforced: true
testable: true
assembly:
execute:
- operation-switch:
version: 2.0.0
title: operation-switch
case:
- operations:
- verb: get
path: /
execute:
- invoke:
title: invoke
version: 2.0.0
verb: keep
target-url: $(target-url)
follow-redirects: false
timeout: 60
parameter-control:
type: blocklist
values: []
header-control:
type: blocklist
values: []
inject-proxy-headers: true
- operations:
- verb: options
path: /
execute:
- set-variable:
version: 2.0.0
title: set-variable
actions:
- value: https://*.ibm.com
type: string
set: message.headers.Access-Control-Allow-Origin
- set: message.headers.Access-Control-Allow-Headers
value: Origin, X-Requested-With, Content-Type, Accept
type: string
- value: POST
type: string
add: message.headers.Access-Control-Allow-Method
otherwise: []
finally: []
activity-log:
enabled: true
success-content: activity
error-content: payload
paths:
/:
get:
responses:
'200':
description: success
schema:
type: string
consumes: []
produces: []
security:
- clientID: []
options:
responses:
'200':
description: success
schema:
type: string
securityDefinitions:
clientID:
type: apiKey
in: header
name: X-IBM-Client-Id
security: []
schemes:
- https