How do Browser Extensions such as "memonic" associate data with a specific user?
cookies, firefox-addon, google-chrome-extension, javascript, session
Solution
My question, how does this work in a browser extension? My understanding is that extensions do not use "sessions" or "cookies", although I'm guessing there is a way to store local data
(I do code and function reviews for addons.mozilla.org, so are more knowledgable about the Firefox side of things, but in Chrome it should be pretty much the equivalent)
Well, some add-ons make use of cookies and other web technologies, but mostly when it comes to extensions of this kind, the authors opt for something like this
- Create a server endpoint that is easily consumable by code via XMLHttpRequest-style AJAX, usually a REST API endpoint of some sort.
- Extensions usually have access to some API that is either XMLHttpRequest itself or resembled it (e.g. Firefox Add-on SDK, Chrome])
- Upon user interaction, the extension will issue XHR/Ajax calls to perform whatever action is needed, query information, register accounts, log a user in, submit new data, etc.
Extension APIs usually provide multiple ways to store and retrieve data, from plain text files, key-value stores to relational databases (WebSQL/IndexedDB), e.g. Firefox Add-on SDK `simple-storage`, Chrome `chrome.storage`. Also, there might be APIs to store login credential securely (e.g. `passwords` module)
It's up to you to figure out what kind of data you need to store locally in the browser and what type of storage is best suited for that.
In general, an extension can do what a web site can do plus some more. (In Chrome via the `chrome.*` extension APIs, in Firefox you can basically do everything that Firefox can do, and that is everything a normal program can do).
But how would you pass a unique id (to identify a user) from the server to the browser extension?
How and if the API maintains (login) state is really up to you and depends on your (existing) design
- Send user:password with each request
- Have a login API that will either set an appropriate cookie or return some kind of session token that will be used subsequent requests
- Use protocols such as OAuth2
Should this unique id originate on the server (like php's session id), or should the client (browser plugin) generate it and send it to the server?
That's up to you, but to me it would make sense that the server generated true unique ids, as it usually has knowledge about what ids are still available, instead of a browser extension generating pseudo-unique ids that still has slight probability to collide with ids other browser instances (other users) may generate in parallel.
Second use case: A user visits the news site, selects the text, right clicks to choose a menu item which saves the selected text to their account. They aren't required to visit the "home" site. This is pretty much what Memonic's Firefox extension does.
The add-on would provide a menu item, get the selected text on click and send this off to the server via a background API Ajax call (providing auth information either within the request or having authenticated before).
2) user is allowed 10 free "clippings" before registering an account
- The extension could ask the server (make an API call) to issue some kind of temporary user id and send that with each "clipping" request.
- After 10 such "clipping" requests, the server would return an error telling the extension that "free clippings" are exhausted.
- At which point the extension would ask the user something along the lines of "No more free clippings. Register an account to get unlimited clippings", e.g by opening such a registration page on your server in a new tab (or other, secondary UI).
- When opening the page, the extension could already pass the temporary user id to the page (e.g. via a GET parameter, or by setting up a cookie or request data or request header), so that upon successful registration the already made "clippings" would be associated with the new full account.
- The extension could also monitor the registration progress to automatically pick up login details.
[Montioring registration] how is this accomplished?
Easiest way probably would be to attach a content-script and either scrape the information directly off the DOM, or have the site issue a regular DOM event the content-script then would process.
Some people also opt to have the whole registration stuff not done via a regular website + form, but using HTML just to create some UI controlled by the extension. The extension would then read out the registration fields once the user clicks the register button and make another API call to perform the actual registration, to which the server would reply with a success or error code. Upon success, the extension will then remember the login information and use it subsequently.
PS: Here is a full example extension using the Firefox Add-on SDK with a context menu item that when clicked will query a web service (API endpoint, no authentication required here) to notify the user about the registrant of the TLD of the current tab. It doesn't fully translate to your specific use case, but is a good, simple demo to show some stuff that you probably need later and to give you a glimpse into what such an extension could look like.
var cm = require("sdk/context-menu");
var notifications = require("sdk/notifications");
var {Request} = require("sdk/request");
var {Cc, Ci, Cu} = require("chrome");
Cu.import("resource://gre/modules/Services.jsm");
cm.Item({
label: "Whois Registrant",
contentScript: 'self.on("click", function (node, data) {' +
' console.log("clicked", location.host);' +
' self.postMessage(location.host);' +
'});',
onMessage: function (domain) {
domain = Services.eTLD.getBaseDomainFromHost(domain);
Request({
url: "http://www.restfulwhois.com/v1/" + encodeURIComponent(domain),
headers: {"Accept": "application/json"},
onComplete: function (response) {
var msg;
try {
msg = "Registered via:\n" + JSON.stringify(response.json.registrant, null, 2);
}
catch (ex) {
msg = "Failed - " + ex;
}
notifications.notify({
title: domain,
text: msg
});
}
}).get();
}
});
Problem
Say you have a "home" website for some kind of "save my favorite clippings" service, where users can register accounts, and then save snippets of their favorite quotes or other text to a personal collection ( one example of this kind of site is "Memonic" : http://www.memonic.com/, among others I'm sure). First use case : A user visits their favorite news site, selects & copies some text, switches to a tab with the "home" (clipping) site loaded, pastes into a form, and then saves the selected text to their account. Second use case : A user visits the news site, selects the text, right clicks to choose a menu item which saves the selected text to their account. They aren't required to visit the "home" site. This is pretty much what Memonic's Firefox extension does. So in the first use case (browser), assuming a PHP-based architecture, the server identifies the user from the cookie passed from the browser in the request. The cookie contains the session_id, unique for that user, which the server users to find the session data, which contains the user_id. The user_id is then used to insert a record into a database. My question : how does this work in a browser extension? My understanding is that extensions do not use "sessions" or "cookies", although I'm guessing there is a way to store local data. But how would you pass a unique id (to identify a user) from the server to the browser extension? Should this unique id originate on the server (like php's session id), or should the client (browser plugin) generate it and send it to the server? To elaborate on the second use case a bit: user downloads & installs browser extension, but is not registered user is allowed 10 free "clippings" before registering an account user visits a news site, starts "clipping", reaches 10, then clicks "register" in the extension's toolbar. An overlay pops up over the site, containing an iframe, which contains the registration form. User creates username & password, clicks submit. So now, the login credentials (username & password) have been sent to the "home" (clipping) server, and the "home" server has created a new user account with a user_id, and stored in a database. At this point, the the browser extension should know how to identify the user (a user_id or equivalent of a session_id)...how is this accomplished? ps -- I'm really only interested in Firefox & Chrome