2023 Apr 20 12:43 PM
Hi,
In SAP Build Apps, how do I pass a CSRF token in the HTTP header of a CREATE record flow function?
To GET the CSRF token, I added a HTTP request flow function and stored the CSRF token returned by the response in an app variable.
How do I pass the app variable to the next CREATE record flow function?
When I added my data resource, I see the option called 'Common request header', where I added the header parameter name. But, I don't see an option to bind the variable.
2023 Apr 21 1:20 AM
I haven't tried it, but I think this will probably work:
Add the CSRFToken as an HTTP header in the REST Api configuration. Set the Label and Key to "CSRFToken", set Value type to "Text", set Is static to off or false, and Is optional to on or true. That should then add the CSRFToken to the inputs on the Create record flow function. Making the header "Not static" makes it available for a formula or variable binding in the flow function configuration.
Here's what that looks like for a get record collection call that I modified:
2023 Apr 21 8:00 AM
Hello @JoeBinkley ,
Thank you for the response! I am using the Odata integration to call my API.
I set my base URL here and we do not have an option to add HTTP header here unlike REST API integration. However, I see 'Common request header' option. If click this and try to make a list of values, I don't see an option to bind my CSRFToken variable. Not sure if this is the right way!
Does the approach differ for OData integration?
2023 Apr 21 8:01 AM
2023 Apr 21 9:31 AM
I don't have an easy way to test this, but I think this will work. You can use a formula that references an additional input.
First, add the additional input:
Then add the list item to the common request headers. (You can do the value with the formula editor)
In the logic flow, you should see this sort of property sheet:
Note, by the way, the warning below about CORS that is shown when you test the data source. I was testing whether the addition of the token would break the OData call using Web Preview and got an error message. But it did work using the Preview App on iOS.
2023 Apr 21 6:43 PM
@JoeBinkley : I have followed this and passed the CSRF token to the CREATE RECORD flow function. However, I received a 403 error 😞 . I don't see any OData failure logs in my S4 system as well. And yes, I have been able to test these through mobile preview only.
We had followed the same approach to test the APIs(Get token first and pass to POST) from the API enterprise hub and it worked well. Hence, not sure what is being missed when done from Build Apps.
My API is of type ODATAV4 - "Warehouse task" creation. Could you please let me know what is the advised approach to perform a POST operation from SAP Build apps for such ODATAV4 APIs? Is there any blog/post on similar ones? Most of the ones that I referred to were REST API or GET operation in OData.
Appreciate your support!
2023 Apr 21 6:53 PM
Are you using this API:
https://api.sap.com/api/OP_WAREHOUSEORDER_0001/path/post_WarehouseTask
Are you able to setup a BTP destination? That's generally an easier way to communicate with SAP systems.
2023 Apr 21 7:13 PM
Yes, that is the API I am using.
No, haven't set up the BTP destination. If we set up a BTP destination, in the build apps, do we use 'SAP BTP destination REST API integration' instead of OData integration to perform the POST operation with the API?
2023 Apr 21 7:58 PM
Using BTP destination is done using the ADD INTEGRATION button just above where you see "SAP Build Apps classic data entities". Using that will require your web app to use BTP Authentication. There is an issue now where BTP authentication does not work in mobile preview.
2023 Apr 25 12:02 PM
@JoeBinkley : Thanks for the inputs! I have been able to get this working.
The approach was same, use HTTP flow function to get the CSRF token. Additionally, pass the X-CSRF-TOKEN ~ FETCH in the header. Store the CSRF token in a variable. Then, use the 'Create record' flow function and pass the CSRF token here. To pass the CSRF token to a OData data resource, need to add an additional new input (approach is the same as in your reply).
The only difference for this API was, I created a data record and passed it.
Earlier, I was passing the field level inputs at the record level and there was a failure. Not sure if it is needed this way for this specific API. But, this is my logic in the canvas now:
Btw, the BTP destination feature works really well too and it did not involve the hassle and fetching and passing CSRF token. But, the mobile preview doesn't work and we have features like scanning a barcode on our app and those do not work in web preview. So, we have planned to stick with this workaround for now.
Thanks for the support 🙂 !
2023 Apr 25 1:20 PM
That's great news. I'm glad it worked out.
And, thanks for letting other Builders know how you did it!
2023 Nov 17 5:19 PM - edited 2023 Nov 17 5:20 PM
Hi Joe,
I'm facing the exact same problem where I need to fetch the CSRF token. My issue is we have to use our cloud connector as to avoid any CORS issues. However, per HTTP Request flow function, we can only pass a text string to the URL parameter. Is there any way to reference our BTP destination via formula ?
If we use the Get Record Collection we cannot access the headers, even though we can see the csrf token being sent in the server's response.
Thanks!
BR,
Gonçalo
2023 Nov 18 12:36 AM - last edited on 2023 Nov 18 2:45 AM by Former Member
Hello @Goncalo ,
You can avoid CSRF token requirement by setting this parameter to 0 at the Service level in the backend. Print screen below.
Another way is to make the Get call first with X-CSRF-TOKEN ~ FETCH in the header. It gives you the CSRF token. Then you can pass on this along with the Post call.
Thank you,
Venkat Vyza
2024 Mar 25 2:58 PM
Hi @Goncalo ,
This is exactly where I am stuck too. I do not have control over backend to whitelist the Frontend as exception for CORS error, so direct HTTP call to the backend is ruled out to fetch the CSRF Token. Next I was exploring on fetching the token via BTP Destination using HTTP request instead of going via Data variables as they won't expose the response headers. I am stuck at a place where the destination is not exposed via formula to be consumed in the HTTP request call.
Would love to know how you were able to get around this problem? I would not prefer to hardcode the destination URL in the HTTP request call, that would be my last resort though!
Thanks,
Raj Pawan Gumdal