How Apps framework client.request works

Have more questions? Submit a request

21 Comments

  • Amos Shacham
    Comment actions Permalink

    Hi,

     

    Thanks so much for this information.

    For some reason, when I try to use the proxy service (by not specifying cors:true in the request), it doesn't work.

    I can see in the network pane of the browser that indeed a request was made to the proxy service, but in my server I can see the incoming request and it does include an "origin" header.

    What am I doing wrong?

    Thanks,

    Amos

     

    1
  • Bryan - Community Manager
    Comment actions Permalink

    Hi Amos -- I know you have a ticket open on this and the issue is being investigated. Explicitly setting "cors:false" seems to keep the proxy from sending the ORIGIN header when using Chrome. This can be used as a workaround in the meantime. For further communications, please use the ticket that you're assigned. Thanks again for raising this!

    0
  • Amos Shacham
    Comment actions Permalink

    Hi @Bryan,

     

    I do have a ticket open but I will also update here that adding "cors:false" doesn't change anything in the behaviour and the "origin" header is still being sent.

    Amos

    0
  • Bryan - Community Manager
    Comment actions Permalink

    This was moved to a ticket but to close out this conversation for others, headers that the browser passes to the proxy service are passed on to the eventual endpoint. So in this case, Chrome was passing ORIGIN to the proxy, which then passed it on.

    The mention in the above comment about explicitly setting cors:false not making that happen was false -- sorry for any confusion. There was testing with Firefox, which has differences from Chrome, which created some confusion (for those who are interested, this Stackoverflow post describes the differences really well).

    0
  • Amos Shacham
    Comment actions Permalink

    Thanks Bryan for clearing this out, but I think I'm not following.

    Wasn't the purpose of the proxy to allow us to make server side requests? So we can avoid the CORS issue?

    I guess what I'm asking is:

    1. What's the point of CORS:false if it still sends the origin header?

    2. How do we make non-cors, server-side requests?

     

    Thanks,

    Amos

    0
  • Bryan - Community Manager
    Comment actions Permalink

    A CORS call is interesting (and can be confusing) in that it is actually the browser that determines if the final response received should be rendered. 

    In other words, it is the browser that determines if the call's response should be rendered or not based on primarily these two points 1) different origin was called 2) Access-Control-* headers received in the response and their values.

    With cors:false, the call is made via a backend proxy, not directly from the browser. Thus, the proxy does not care about where the call is going or what Access-Control-* headers it gets back. It just makes the call, receives the response, then passes it back to the browser. Kind of like if you were making the call from a tool such as cURL on the command line -- there is no concept of origin in that context. 

    And since the call from the browser to the proxy (when setting cors:false) is *same origin*, there is no possibility of a CORS failure. So with this feature, you can make calls to other services that typically wouldn't allow a direct cross-origin call from a browser.

    As a side note, if you are making API calls directly from a browser (and not through a proxy), this article might also be helpful: CORS Troubleshooting

    The bottom line is that, if you have a remote server that typically doesn't allow cross-origin calls, you might be able to work around the limitation by going through a proxy. The free proxy that Zendesk Apps framework provides helps facilitate that kind of scenario.

    0
  • Bryan - Community Manager
    Comment actions Permalink

    Added this point of clarification in the "Method 3" section of the above article -- if a browser passes an ORIGIN header to the proxy, the proxy will pass it along to the remote server.

    0
  • Amos Shacham
    Comment actions Permalink

    Hi Bryan - Community Manager,

     

    I don't understand the point of the proxy if it mimics the browser request.

    The whole idea of the proxy is to be able to avoid CORS checks. This is what this article is all about.

    Correct me if I'm wrong, but the origin header is what makes the request a CORS request. It doesn't matter who sends it - whether it's the browser or a server. The server that receives the request thinks it comes from a browser if it has that origin header.

    If Zendesk server also send this header - how can we avoid or get around CORS?

    Thanks,

    Amos

    0
  • Amos Shacham
    Comment actions Permalink

    Bryan - Community Manager - In addition, when the browser is detecting a post request to a different domain, it first preflight the request with an OPTIONS verb request - does that mean Zendesk proxy is doing the same?

    Again, from my understanding, the purpose of the proxy (cors:false) is to get over a cors request. But if the proxy does exactly what the browser is doing (adding origin header and sending an OPTIONS request) - how is this helping in that?

    I think the point is that when we're using ZAF's request option, and tell it all the details of our request, it should be sent to the proxy and from there to the our endpoint as we asked it to be - so if we asked for a POST request without an origin header, don't add one... no?

    0
  • Bryan - Community Manager
    Comment actions Permalink

    Hi Amos. It's browsers on their own that will create OPTIONS calls. Since the API call is coming from our backend proxy service (not a browser), there will be no OPTIONS call.

    Also, the proxy just passes the ORIGIN header through if it receives it. It won't add it on its own. I think the point to clarify is that the initial call to our proxy is coming from a browser. So despite an ORIGIN header not being explicitly added in your code, the browser will add it automatically. That's not Zendesk doing it, it's the browser.

    Edit: And as far as the call from the front-end browser to the back-end proxy, those are in the same domain. The browser will not generate an OPTIONS call on the same domain.

    0
  • Amos Shacham
    Comment actions Permalink

    OK, so please tell me if I got this right or if I missed something - the request from the browser to the proxy is SAME ORIGIN, *but* if you use a "post" request, then, according to the specs, this now becomes a CORS request. The browser won't send the OPTIONS preflight, but it will add the ORIGIN header.

    Your server will send this to the remote server, which might only support backend requests and not CORS request. So when the request will get back to the proxy and to the browser, it will not have the CORS needed headers, and the browser will block it.

    Am I correct in all this?

    How can we then make non-CORS POST requests? Can Zendesk ignore the ORIGIN header when cors:false is used (even though the browser do send one)? And if so - will that solve the problem?

    Thanks,

    Amos

    0
  • Bryan - Community Manager
    Comment actions Permalink

    >>>>

    tell me if I got this right...the request from the browser to the proxy is SAME ORIGIN

    <<<<

    That is correct. When calling the proxy, it is always same origin, regardless of action. That's because the proxy is always called under the same domain as the account.

    This is the format of the call to the proxy (also mentioned in the above article):

    https://yoursubdomain.zendesk.com/proxy/to/https://api.github.com

    The remote API endpoint the proxy will call is always tacked to the end of proxy endpoint.

    And because it is always a same origin call, the browser is not looking for or expecting cross-origin Access-Control-* headers in the response.

    0
  • Amos Shacham
    Comment actions Permalink

    >>>>>>>

    And because it is always a same origin call, the browser is not looking for or expecting cross-origin Access-Control-* headers in the response.

    <<<<<<<

    This is where I think you're wrong, and correct me if I'm wrong, cause I'm no CORS expert. But from what I read in the specs, if it's a POST call, then even if it's to same origin, the browser *is* looking for the cors headers.

    If I'm right, I guess that means that the zendesk proxy *should* return the CORS headers for same origin POST calls, as it indeed approves them.

     

    No?

    0
  • Bryan - Community Manager
    Comment actions Permalink

    Hi Amos. You can actually try this out by setting up a third-party service and endpoint using something like glitch.com. You can make a POST call to it via client.request with cors:false, receive the request in your remote server, and not send back any Access-Control-* headers, just a response payload. You'll get the payload and the browser will not complain about the lack of Access-Control-* headers. Can you give the link to the specification reference where a POST expects Access-Control-* headers?

    0
  • Evandro Lopes Abu Kamel Costa
    Comment actions Permalink

    Hello, everyone.

    We are experiencing a very strange behaviour when sending a POST request with ZAF Client. We are using the options cors: false because we weren't able yet to solve the CORS issue.

    So, our payload is something like:

    {
      "operator": {
        "email": "my-email@domain.com.br"
      },
      "rebooking": {
        "idTransaction": "4294711",
        "desistance": false
      }
    }

    We're making the request like:

    const result = await zafClient
    .request({
    url: 'https://postb.in/1590517967100-7047247027512',
    method: 'POST',
    dataType: 'json',
    contentType: 'application/json',
    data: JSON.stringify(payload),
    cors: false,
    })
    .then(
    (response) => {
    console.log(response);
    return response;
    },
    (response) => {
    console.error(response);
    return response;
    }
    );

    But the request is sent like this, each character from the payload becomes a parameter in query string and nothing goes on the body.

    I thnik this is a bad implementation of the POST request because it is expected that the data goes on the body, not on the query. I need to send some complex data structure and that is not possible using the ZAF client proxy.

    If I send my data without JSON.stringify, I recieve:

    operator: [Object object], rebooking: [Object object]

    Do you guys have any ideias how to solve this, please? Is there anything that can be done? Is that a bug or technical decision for ZAF client to act this way?

    Thank you.

    1
  • Comment actions Permalink

    Well, we've managed to solve the CORS problem, so, we're using the cors: true option. Thanks.

    0
  • Greg - Community Manager
    Comment actions Permalink

    Thanks for the update, Evandro. I'll keep this open in case anything else comes up that I can help out with!

    Greg Katechis | Developer Support and Enablement Engineer

    0
  • Samir Sarkar
    Comment actions Permalink

    Hi Bryan,

    I created a custom app to get the data from an third party application (SAP successfactor application).

    I a getting the below notification  when the app is getting loaded first time  ( asking api userid and password) .but i have already provided he credentials at the time of installation .

    When  I am providing the API credentials at pop up , that time i am able to get the data.

     

    Failed to load resource: the server responded with a status of 401 ()

    https://Myinstance.zendesk.com/proxy/to/https%3A%2F%XXXX.successfactors.com%2Fodata%2Fv2%2FUser(XXXXXX)%3F%24expand%3Dmanager%2Chr%26%24format%3DJSON

    NOTE: I am using Basic Authentication Process .

     

    Thanks 

    Samir Sarkar

    0
  • Bryan - Community Manager
    Comment actions Permalink

    Hi Samir Sarkar. I'm not sure why that dialog would be coming up. A remote API request using the proxy shouldn't be bringing up any login dialogs.

    Can you provide the code that is calling the remote API? Can you also take a look at your browser's Network tab when the call is made to see if any errors or issues are surfaced there?

    Edit: answered in private ticket.

    0
  • Alex S.
    Comment actions Permalink

    Hi Bryan, thanks for covering all the different options we have in Zendesk!

    With a server that is not accepting cors, I am using the Method 3 and pass the following GET request header through client.request(): 'x-csrf-token': 'Fetch'. Unfortunately the header is not being sent at all.

    Would you have any idea why this happens? I can see it when setting client.request to cors: true or using $.ajax, etc. but cannot use it since the server is not cors-compliant.

    Thanks!

    0
  • Bryan - Community Manager
    Comment actions Permalink

    Hi Alex. client.request will not send x-csrf-token — this is a reserved header that Zendesk Support uses when managing requests. In fact, it's not something a client would typically set. It comes from the server, to be sent back by the client during normal communication though a browser-to-server communication. If you're going through a proxy, you are really approaching things from a different angle.

    0

Please sign in to leave a comment.

Powered by Zendesk