How to Solve CORS Issues with SAP API Management

As more and more SAP Folks are joining AppGyver I see that we are all struggling with the Cross-origin resource sharing. After trying to find a solution for a long time, a blog post about AppGyver in SAP Blogs helped me out. I decided to prepare a step by step guide here on AppGyver.

In this tutorial we will cover how we can overcome the CORS using SAP API Management. Obviously, CORS issue is not only related with SAP Applications and SAP APIM is one of the many tools to solve this issue.

What is CORS?
Cross-origin resource sharing (CORS) protects your backend by allowing only the allowed domains to access your system. When you’re trying to access an when you’re making a request from here, platform.appgyver.com is requesting to access your system. Since this platform is unknown to your backend, the system returns an error.

Question: How can I access my SAP Application without getting CORS error?
Answer: Unless your backend has CORS support (i.e. whitelisting) you should use an API Proxy.

Prerequisites
You should have access to SAP BTP. Trial available here.
You should add Integration Suite to your BTP Account. Follow this tutorial to learn how.

Creating an API Proxy

As a C4C Consultant, I’ll be using C4CODATAAPI to access my backend.

Open APIM and Click Discover, then search for your solution.

Select the service that you’d like to use and click on Copy. Add your domain or if you’d just like to tag along with me, use SAP’s sandbox api (get your apikey from API Business Hub).


Alternatively, if you can’t find your solution or want to build it from scratch, you can go to Develop and click Create

Handling CORS
To deal with CORS, you need to make a preflight call with OPTIONS and set the relevant headers.

Open your API Details and Click Edit. Go Proxy EndPoint tab and delete the default route rule.
Then add the rules as you see below. Note that the noroutes should be on top.

"Route Rule Name:" noroutes
"Route Rule Condition:" request.verb == "OPTIONS"

After adding the rules, click on Policies

In Flows → ProxyEndpoint click Add (+) and add the following flow

"Flow Name:" preflight
"Condition String:" request.verb == "OPTIONS"

Click on ProxyEndpoint → PostFlow. From the policies on the right side, select Assign Message. Stream should be Outgoing.

Paste the following code to the script.
Note: In “Access-Control-Allow-Headers” I have added “authorization” header. If you’re planning to use API Keys, add “apikey” to the allowed headers. Basically add any necessary headers that you need to pass.

<!-- This policy can be used to create or modify the standard HTTP request and response messages -->
<AssignMessage async="false" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
    <Add>
        <Headers>
            <Header name="Access-Control-Allow-Origin">*</Header>
            <Header name="Access-Control-Allow-Headers">set-cookie, origin, accept, maxdataserviceversion, x-csrf-token, authorization, dataserviceversion, accept-language, x-http-method, content-type, X-Requested-With</Header>
            <Header name="Access-Control-Max-Age">3628800</Header>
            <Header name="Access-Control-Allow-Methods">GET, PUT, POST, DELETE</Header>
            <Header name="Access-Control-Expose-Headers">set-cookie, x-csrf-token, x-http-method</Header>
        </Headers>
    </Add>
    <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
    <AssignTo createNew="false" type="response">response</AssignTo>
</AssignMessage>

Click on Update

Save and Deploy your API.

Now let’s test our API. Copy your API Proxy URL. Open AppGyver and Click on Data and add a Data Resource. You can both use REST API and OData Integration. To keep it short, let’s use OData Integration

Paste your API Proxy Link and Click Verify

Save the Data Resources that you want. That’s it!

Note: Do not save them all as it is causing serious performance issues. Only activate the ones you really need and will regularly use in different pages or with different cases. In case you need a simple call that you only going to use in one page, use HTTP Request Flow instead.

You can access the detailed SAP Guide from here.

7 Likes

Good stuff, thanks!
However, one comment to your blog: if you are not acquainted with API Management, you may have some trouble if you are using policies in the “preflow” flow. Indeed, theses policies always get executed, such as “Verify API Key” or any other one. So when the “OPTIONS” method is used for CORS-purpose, the policies of the pre-flow will be executed… even though you don’t send an API-key. Result?


It looks like a CORS issues, but the real issue is that API Management doesn’t find the API key and throws an error, which is mistakenly interpreted as CORS issues. The solution would be to execute the “Verify API Key” only if the HTTP Method is not “OPTIONS”:

HTH!
-s

1 Like

Hi

I’ve followed your guide, but it still shows “CORS” error while running web preview page of AppGyver.
Have you successfully seen the results in the web preview page of AppGyver?
Please let me know if you provide further advice.

Best Regards
Jungwoo.

Yes, I did actually, the last screenshot shows that the GET request was successful.

If you followed the exact steps (basic auth etc.) then most likely your issue is not CORS but something else, even though it says CORS (like @Sven_Huberti mentioned).

i Have an image url from instagram, and because of instgrams cors policy, the images dont work in my page.
Is this solution applicable to my problem?

Could be, there are some solutions here: Instagram web api get: :ERR_BLOCKED_BY_RESPONSE - Stack Overflow

But if your app is outside SAP, I’d suggest using another proxy management tool. Maybe something more affordable (yes, I’m looking at you SAP).

1 Like

i see what you mean, i will consider both of you suggestions, Thank you very much!

Hi,
Thanks for the tutorial.
I have followed this tutorial and configured the API proxy and was able to fix the CORS issue for GET request. But for POST request still I am getting the CORS issue from the browser.
If am triggering from mobile the POST is working correctly. Is there anything additional I need to add in Policies in API for POST to work?
Can you please help me to fix the issue in triggering POST from Browser.

image

Thanks,
Anjaly

If it is working for GET but not for POST, then it is likely to be another error but AppGyver can’t understand what it is so it assumes it might be CORS. Can you please open Developer Console (F12) and check the network tab with the error message?

When I am doing the POST from mobile, It is working. The issue is from browser. I am getting the below error in Console.

Regards,
Anjaly

Hello Experts,
I am also getting an CORS error while doing a POST operation.
Please suggest how to resolve this issue?

Thanks
Shyam

I have same issues on my end which is can be perform GET, but not for POST,
did you have any update, please share

Hello ,

Thanks for the tutorial, I have resolved the problem with CORS for the GET method following the steps. However I still have a CORS issue when I try to POST data into the same API using AppGyver. I can POST Data using the testing tool of SAP API Portal but I can’t post using AppGyver ?

Does anyone have an idea ?

same issue here, works for GET not for POST

guys you have to use a proxy ther is no other solution, in my case im using firebase functions.