Page 1 of 2 12 LastLast
Results 1 to 10 of 13

Thread: Authorization header not sent on preflight OPTIONS request

  1. #1
    Sencha Premium Member
    Join Date
    Feb 2013
    Posts
    5

    Question Authorization header not sent on preflight OPTIONS request

    I'm using a 'rest' proxy in my store, I have default headers set like so.

    Code:
    Ext.Ajax.defaultHeaders = {
      'Accept' : 'application/json',
      'Content-Type' : 'application/json',
      'Authorization': 'Bearer ' + AiPatientEditor.util.Config.accessToken.access_token
    };
    and my proxy in the model is configured to add the header:

    Code:
      proxy: {
            type: 'rest',
            url: 'removed',
            extraParams : { format : 'json' },
            headers: {
              'Accept': 'application/json',
              'Authorization': 'Bearer ' + AiPatientEditor.util.Config.accessToken.access_token
            },
            reader: {
                type: 'json',
                root: 'results',
                totalProperty: 'count'
            },
            writer: {
                type: 'json'
            }
        }
    Now my application does function properly on the surface and it sends the authorization header properly except on the pre-flight OPTIONS request.

    Upon some further investigation it looks like when the OPTIONS request is done it is not calling the setupHeaders() method in Ext.data.Connection. Does anyone know how I can add the simple Authorization header to my pre-flight requests? I'm having trouble finding where this request is built in the source code.

    I feel like this should be pretty easy to fix with a simple override.

  2. #2
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,791

    Default

    I assume we're talking CORS here?

    The OPTIONS request is constructed automatically by the browser, so you won't find any ExtJS code for building it. As far as I can tell you can't put custom headers on the OPTIONS request, they'll just be moved into the Access-Control-Request-Headers.

    I believe this is the relevant section of the spec:

    http://www.w3.org/TR/cors/#cross-ori...th-preflight-0

    If I'm reading it correctly it seems pretty explicit that all headers and authentication will be stripped from the original request when generating the OPTIONS request.

    A little searching suggests that some IIS users have requested that the spec be altered to allow authentication on the OPTIONS request but thus far this hasn't been added to the spec or implemented in browsers.

  3. #3
    Sencha Premium Member
    Join Date
    Feb 2013
    Posts
    5

    Default

    Yes, CORS.

    That's interesting, thank you for the link. It looks maybe the correct thing to do would be to allow UnAuthenticated OPTIONS requests on the serverside? I don't really see any security risk since the purpose of the preflight is to see whether an operation could be done, or a resource exists.

    Edit: I found this too - https://code.google.com/p/twitter-api/issues/detail?id=2273

    It looks like preflight requests should not require Authentication. At least that's how twitter seems to hand their OAuth2 api.

    MOAR Edit: For anyone who finds this in the future, I found a great plugin for django to handle CORS. https://github.com/OttoYiu/django-cors-headers

    If you using php or another language you should just be able to return a 200 OK for the OPTIONS part.

  4. #4
    Ext JS Premium Member devtig's Avatar
    Join Date
    Jan 2010
    Location
    Rotterdam, The Netherlands
    Posts
    422

    Default

    Great discussion guys!
    I had the same problem (headers not sent with the preflight OPTIONS request). The server would reject the request and CORS could not be enabled. I ended up removing the server side (NodeJS - Express) requirement for the authentication header when
    Code:
    req.method === 'OPTIONS'
    Christiaan Westerbeek @ Devotis
    Contact me for help with Ext JS, Node JS, FireBase, AngularJS and Javascript in general. Email me or find me at AirPair to connect.

  5. #5

    Default

    devtig,
    How exactly did you do this in your Node.JS code. I assume your conditional was
    if req.method === 'OPTIONS'
    , but what did you do to actually remove the server side requirement for the authentication header?

    I am having a similar issue using Flask as the API server and am banging my head against the floor.

    Thanks!

  6. #6
    Ext JS Premium Member devtig's Avatar
    Join Date
    Jan 2010
    Location
    Rotterdam, The Netherlands
    Posts
    422

    Default

    This:

    Code:
    var app = express();
    app.enable('trust proxy'); //http://stackoverflow.com/a/14631683/1385429
    
    //then this before app.router is used
    app.use(function(req, res, next) {
      //Preflight CORS does OPTIONS request without headers. Let's not require Authorization then
      if (req.method !== 'OPTIONS' && req.headers['authorization'] !== 'Token 12345678') {
        res.statusCode = 401;
        return next(new Error('Invalid api key or non provided'));
      }
      return next();
    });
    Christiaan Westerbeek @ Devotis
    Contact me for help with Ext JS, Node JS, FireBase, AngularJS and Javascript in general. Email me or find me at AirPair to connect.

  7. #7

    Default

    Great! Thanks a ton for this.

    What is the purpose of the conditional for
    Code:
    req.headers['authorization'] !== 'Token 12345678'?
    This seems to be checking for a particular instance of a token, yes? If so, then how does this provide a general solution? It seems to always fail then on preflight, since the request method will be a GET, and req.headers['authorization'] will be NULL.

    Also, why do you need to get the remote client's address, as per the stackoverflow thread??


    Thanks again!

  8. #8

    Default

    Alright, I think I am beginning to understand what is happening. The initial 401 error is what should be expected. What is not expected is that the username/password dialog for basic auth is not popping up for Firefox, Chrome and IE, but it is for Safari. Any clues as to why this is not working as expected would be most welcome.

  9. #9
    Ext JS Premium Member devtig's Avatar
    Join Date
    Jan 2010
    Location
    Rotterdam, The Netherlands
    Posts
    422

    Default

    You can send me an email or find me on AirPair for further help. I feel like misusing this thread if I was to answer your questions here.
    Christiaan Westerbeek @ Devotis
    Contact me for help with Ext JS, Node JS, FireBase, AngularJS and Javascript in general. Email me or find me at AirPair to connect.

  10. #10

    Default

    Good point... I started a new post on Stackoverflow, since I do not think this is an ExtJS/CORS issue. It may be an Apache or Flask issue.

Page 1 of 2 12 LastLast

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •