Request Method Switching from GET to OPTIONS alone

Asked

Viewed 2,343 times

2

I have the following code:

$(function() {
    $('#method').change(function() {
        var method = $(this).val();
        if (method == 'GET' || method == 'DELETE')
            $('#json-group').hide();
        else
            $('#json-group').show();
    });

    $('#send-button').click(function() {
        var url = $('#url').val()
        var a = document.createElement('a');
        a.href = url;
        var method = $('#method').val();
        if (method == 'GET')
            var data = '';
        else
            var data = $.trim($('#json').val());
        var md5 = data ? CryptoJS.MD5(data).toString(CryptoJS.enc.Base64) : '';
        var date = (new Date()).toUTCString();

        var parts = [method, md5, date, a.pathname].join('\n');
        var hmac = CryptoJS.HmacSHA1(parts, $('#api_secret').val());
        var sig = hmac.toString(CryptoJS.enc.Base64);
        var auth = 'Zopim-Reseller-API ' + $('#api_token').val() + ':' + sig;
        var headers = {'API-Date': date, Authorization: auth};
         $.ajax({
      url: url,
      type: method,
      dataType: 'json',
      success: function() { alert('hello!'); },
      error: function() { alert('boo!'); },
      beforeSend: setHeader
         });

         function setHeader(xhr) {
    xhr.setRequestHeader('Authorization', auth);
    xhr.setRequestHeader('API-Date', date);
  }
    });
});

This code should send a GET request, but in Chrome it informs me the following data:

Remote Address:67.23.229.9:443
Request URL:https://reseller.zopim.com/api/info
Request Method:OPTIONS
Status Code:200 OK
Request Headersview source
Accept:/
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en,en;q=0.8,en-US;q=0.6,en;q=0.4
Access-Control-Request-Headers:Accept, Authorization, api-date
Access-Control-Request-Method:GET
Connection:Keep-Alive
Host:Seller.zopim.com
Origin:http://zopim.net.br

And as a result of that mistake:

Xmlhttprequest cannot load https://reseller.zopim.com/api/info. Request header field Authorization is not allowed by Access-Control-Allow-Headers.

  • Reading the documentation to /info here: https://sites.google.com/a/zopim.com/reseller/api/info I see that what they want is email and password. Have you tried this or token as header key?

  • Those 2 lines: var auth = 'Zopim-Reseller-API ' + $('#api_token').val() + ':' + sig;
 var headers = {'API-Date': date, Authorization: auth}; They are the ones that form the HEADER for it to do a kind of login to get the information of /info only that it can stay as GET is returning to me as if I had sent OPTIONS

  • And already tried to use the parameters they refer to in the CURL? xhr.setRequestHeader('email', email); xhr.setRequestHeader('password', password); ?

  • No, but they refer to authentification of the auth variable and the 'API-Date' parameter'

  • On this page /info I can’t find anything about authentication with API-Date. Where is this information?

2 answers

2

The problem is Cross-Origin Resource Sharing.

The HTTP protocol considers, as simple requests, the following methods:

  • GET
  • POST
  • HEAD

The others, as OPTIONS, sane Preflighted Requests. OPTIONS in particular serves to ensure the security of the requisition. The data traffic goes to the server to determine if it is secure information or not - if so, the object is "uncompressed" and read in a certain way predicted by the server itself [].

Your dataType, in this case, it is json, your method is GET, and you’re wearing a header customized therefore your request is "preflighted" - which means that unless specified on the server, the method will be OPTIONS.

0

What happens is the following, for HTTP request methods that can cause side effects on server data (in particular, for HTTP methods other than GET, or for using GET with certain MIME types), the specification determines which browsers "pre-send" the request, requesting server-supported methods with an HTTP OPTIONS request method, and then, after "approval" from the server, send the true request with the effective HTTP request method.

By default browsers do not send HTTP Header Authorization in HTTP OPTIONS requests, so your server/API must be requiring Authorization for all HTTP Methods and therefore gives error in the first HTTP OPTIONS request and bar the HTTP GET request.

To fix the issue you must configure your server/API to allow HTTP OPTIONS requests without Header Authorization.

Information collected from:
- HTTP Access Control (CORS) - HTTP | MDN
- Cors - Authorization header not sent with http request angular 6 with OPTIONS method - Stack Overflow

Browser other questions tagged

You are not signed in. Login or sign up in order to post.