简体   繁体   中英

AJAX request - cookie authentication

I am building a little widget (using JavaScript) which needs to interact with a RoR web application via AJAX. The workflow for a user looks like this:

  1. Login to the RoR web app
  2. Get browser extension or bookmarklet (both share the same codebase), whichever
  3. Go to a website and activate the widget
  4. Point stuff on that website you want to get saved, press ok
  5. You get back a URL on the web app with the captured content

The workflow in the widget code looks something like:

  1. Collect stuff from the DOM and issue a relevant jQuery JSONP request
  2. If there's a custom status message in the response reading 'unauthorized', open an <iframe /> with an authorization page originating from the web app — if auth is successful in the response there's a Set-Cookie header setting the auth cookie needed for subsequent AJAX requets
  3. If there's been auth needed, try the JSONP request again

This just works for the bookmarklet. However, for a Firefox extension, the web app receives the requests stripped of the auth cookie. Stripped of all cookies in fact. Seems like the requests are sandboxed. Now I know there's @mozilla.org/cookieService available for extensions. Questions are:

  1. how would I pass a cookie from the extension's main.js to a JSONP request in a content script?
  2. how would I get the cookie for the development env, with url localhost:3000? The cookieService returns null as cookies for that url
  3. is it feasible to change the way authentication is resolved, from cookies to something else?

The requests are not really sandboxed, but lack an origin document. Because of that the network code does not know if the request is a first party or third party request, and will by default treat it as the latter. Firefox disabled sending cookies to third party servers a while ago, and that is why there are no cookies in your requests.

In a XUL/XPCOM add-on you'd do (easiest way):

var req = <construct xmlhttprequest>;
...
req.open(...);
if (req.channel instanceof Components.interfaces.nsIHttpChannelInternal) {
  req.channel.forceAllowThirdPartyCookie = true;
}

Add-on SDK users would can do the following when using net/xhr :

const { XMLHttpRequest, forceAllowThirdPartyCookie } = require("sdk/net/xhr");
var req = new XMLHttpRequest();
...
req.open(...);
forceAllowThirdPartyCookie(req);

The higher-level request module always calls forceAllowThirdPartyCookie automatically.

Now back to your questions:

  1. Do not use JSONP . That is basically the same as eval() ing remote, untrusted code in a (somewhat) secure context. You never know if there are man-in-the-middle attackers around (if using insecure connections) or if the server got compromised (all connections).

    Anyway, content-scripts cannot use the above methods, so you'd have to do the request in privileged code (eg main.js ) and use message passing to pass the response over to the content script.

  2. You really shouldn't use nsICookieService* directly. If you really like to use the service, then read the docs .
  3. You can always switch to another auth scheme I guess. Which one to use and how to do it would depend on your requirements (ie too broad to answer).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM