Making cross-origin, browser-side API requests

Have more questions? Submit a request

17 Comments

  • Andrew Sharpe

    Great writeup, thanks!


    There is one issue with using Zendesk in this way, which is the lack of CORS headers for anything other than a 200 response.


    This article implies that the lack of CORS headers is used as access control however that's built into Zendesk proper.


    If the user making the request does not have permissions to use the API endpoint (as specified by the "Allowed for" sections in the API docs), the "Access-Control-Allow-Origin" header is not included in the response. The missing CORS header prevents the user from accessing the resource in the Zendesk domain.


    The lack of CORS headers for unauthorised requests means that the client application cannot handle issues gracefully.  Zendesk is actually returning a 401, which indicates correctly the reason why the user cannot access the resource.  The same applies if the token is invalid/expired, and the app cannot make an intelligent decision without the CORS headers in the response.


    Another example is the "429 Too Many Requests" response that Zendesk can return.  Because this response doesn't have CORS headers the application does not get a chance to identify this issue and respond accordingly.


    Could Zendesk please return the CORS headers for requests that fail too?

    0
  • Charles Nadeau

    Thanks very much for the feedback, Andrew. I updated the wording in the article to make this clearer. 


    I ran some quick tests and I'm able to confirm that the headers are returned on 200, 201, 204, and 404 responses. Not sure if there are any others.


    I brought this issue to the attention of the API product team.

    0
  • Manoj Tammali

    Hi Charles,


    I have tried to implement the same on my Zendesk (konysolutions.zendesk.com) but the code always stops after executing "startAuthFlow" method. It redirects me to my Zendesk page rather than giving me the ticket details as said on the above html. What could the potential problem with this. I have no console errors as well on the above html page. Please do let me know.


    Thanks,


    Manoj


     

    0
  • Charles Nadeau

    Hi Manoj,


    Can you share your startAuthFlow() function? It should look like this (with different values for your_redirect_url and your_unique_identifier:


    function startAuthFlow() {
    
    var endpoint = 'https://konysolutions.zendesk.com/oauth/authorizations/new';
    var url_params = '?' +
    'response_type=token' + '&' +
    'redirect_uri=your_redirect_url' + '&' +
    'client_id=your_unique_identifier' + '&' +
    'scope=' + encodeURIComponent('read write');
    window.location = endpoint + url_params;
    }

     

    0
  • Manoj Tammali

    Hi Charles,


    this is the code.


     


    function startAuthFlow() {
     alert("startAuthFlow Starts");
      var endpoint = 'https://konysolutions.zendesk.com/oauth/authorizations/new';
      var url_params = '?' +
      'response_type=token' + '&' +
      'redirect_uri=https://konysolutions.zendesk.com' + '&' +
      'client_id=konysupport_cseoauth_token' + '&' +
      'scope=' + encodeURIComponent('read write');
      window.location = endpoint + url_params;
      alert("startAuthFlow ends");
    }


    One thing i am not sure is what the redirect_uri means. the value i have put here is there in my OAuth token. but why and what the redirect URI does is what i am not sure.


    Please help me on this.


    Thanks


     

    0
  • Charles Nadeau

    The "redirect_uri" is one of the "Redirect URLs" defined when creating the OAuth client in the Zendesk admin interface: 



     

    0
  • Manoj Tammali

    Hi Charles,


    It is the same url that i have put in code. but doesn't work.


    0
  • Charles Nadeau

    Hi Manoj,


    Sorry about that. I wasn't clear about the redirect url in the article. I updated the article with the following info:


    ---


    For the Redirect URLs field, enter the URL of the web page you'll build in this tutorial. Looking ahead, the file will be named ticket_details.html.


    If you have access to a web server, enter the full url to the future file:


    https://www.example.com/my_site/ticket_details.html


    If you don't have access to a web server, you can install and run a local web server such as XAMPP on your computer. Specify a localhost url as a redirect url. Example:


    http://localhost/my_site/ticket_details.html


    For more information on XAMPP and to download it, see the Apache Friends website.


    ---


    You should then save or upload all 3 files, ticket_details.html, styles.css, and scripts.js, to the folder to be served by the web server. Make sure the url for ticket_details.html is the same as the redirect url you specified in your OAuth client.


    Charles

    0
  • Jon I.

    Hi!


    I'm facing an issue with Ticket Imports.


    Cors policy states that when a resource is protected by any kind of authentication mechanism (http basic, token...) Access-Control-Allow-Credentials cannot be '*' (everywhere).


    I'm trying to implement an application which makes use of Ticket Imports and I cannot use it:



    Is there something I can do? I believe the AJAX call is being performed correctly, but the answer isn't well (the ticket gets created but I receive that error).


     My code snipet:


    var request = new XMLHttpRequest();
    request.withCredentials = true;
    var url = "https://***.zendesk.com/api/v2/imports/tickets.json";
    request.open('POST', url, true);


    request.setRequestHeader("Authorization", "Basic *****");


    request.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {


    // do something


    }else{


    // do something else


    }


    };
    request.send(jsonObjStr);

    0
  • Charles Nadeau

    Hi Jon,


    Zendesk only implements CORS for API requests authenticated with OAuth access tokens, not basic authentication. Example:


    request.setRequestHeader("Authorization", "Bearer " + access_token);

    See the article above for all the gory details of getting and using an OAuth access token.

    0
  • Vivace Cho

    Hi

    I want to use API with localhost, so I've made OAUTH with http://127.0.0.1:8080/zoauth/ticket_details.html

    However, it keeps giving me 'invalid_token'. The only thing I changed from your demo code is putting my OAUTH token in makeRequest() manually like 'makeRequest(oauth, ticket_number)'.

    But it keeps giving me 401 unauthorized.


     

    0
  • Klara Audren

    Hello Vivace,


     


    The token should be specified in the "request.setRequestHeader",please try the below


      request.setRequestHeader("Authorization", "Bearer " + token);

    0
  • Dirk Wolthuis

    If I want to make a app that creates and reads tickets for unauthenticated end-users, who would I set up authentication with the Zendesk API? Or end-user do not have a Zendesk-account.

    0
  • Bryan Flynn

    Hi Dirk,

    If you're looking to have end users create (which does not require authentication) and read their associated tickets (which does require authentication) then you should check out the /api/v2/requests.json API endpoint. It's the API that end users should used (versus the /api/v2/tickets.json endpoint, which is for agents).

    This also might be a useful article:

    Building a custom ticket form with the Zendesk API

    0
  • Willie

    I'm getting some very strange behavior when attempting to make a call to an API endpoint from within a custom ticket sidebar app. Any help would be appreciated! 

    client.get('ticket.requester.id').then( requestID => {
    var requester_tickets_url = "https://crunchyroll.zendesk.com/api/v2/users/" + requestID['ticket.requester.id'] + "/tickets/requested.json";
    console.log(requester_tickets_url);

    var r = new XMLHttpRequest();
    r.open("GET", requester_tickets_url, true);
    r.setRequestHeader('Authorization', 'Bearer ' + oauth_token)
    r.send();
    r.onreadystatechange=(e)=>{
    console.log(r.responseText)
    }

    });

    The console returns the following error:


    Access to XMLHttpRequest at 'https://crunchyroll.zendesk.com/api/v2/users/1380055993/tickets/requested.json' from origin 'https://162861.apps.zdusercontent.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

    Additionally, per the instructions, what should I put as the "redirect_url" when the app is being run from the ticket sidebar? 

     

    Thanks!

     

    ------------------ 

    Update: Issue is Resolved. Seems like using an Oauth key from the following locaiton did the trick: https://developer.zendesk.com/requests/new rather than Admin > Channels > API > Oauth

    0
  • Bryan Flynn

    Glad you got things going Willie. Just to point out and for reference, grabbing an OAuth token from the location you mentioned is a quick way to generate one for Zendesk Support but will not work for other Zendesk products (such as Chat). This article also has some good tips for generating OAuth tokens for Zendesk Support: Using OAuth authentication with your application

    0
  • Warpist

    Check out https://warpist.com as it provides managed CORS proxies to get around this issue while still being able to configure the headers precisely.

    0

Please sign in to leave a comment.

Powered by Zendesk