Reputation: 5
What is the best way to remove browser cookie from fire fox extension ? I have use the following code :
var date = new Date ();
var expi = new Date(date.getTime() + usertime*60000); // how long to stay login
var cookieMgr = Components.classes["@mozilla.org/cookiemanager;1"]
.getService(Components.interfaces.nsICookieManager);
for (var e = cookieMgr.enumerator; e.hasMoreElements();)
{
var cookie = e.getNext().QueryInterface(Components.interfaces.nsICookie);
if(cookie.host == tmpUrl) // for check is the current page
{
var cookieString = '"'+cookie.name+"="+cookie.value+";domain="+tmpUrl+";expires="+expi+'"';
var cookieUri = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService)
.newURI(url, null, null);
Components.classes["@mozilla.org/cookieService;1"]
.getService(Components.interfaces.nsICookieService)
.setCookieString(cookieUri, null, cookieString, null);
}
}
The code is working. After given time of interval user get loged out. But after loged out when user hit the same url it goes to 401 page. I am new in firefox extension developer. So please help me.
Upvotes: 0
Views: 421
Reputation: 33366
MDN refs:
Your question asks about removing cookies, but that is not what your code does. What are you actually trying to do?
There are multiple variables which are used that are not defined. We have to assume what these are supposed to represent. These include: date
, tmpUrl
, url
, and usertime
. It is assumed that tmpUrl
is actually the domain and url = "http://" + tmpUrl;
Problem 1: expi is defined as a Date
. You are using it where it is supposed to be text. You should be specifying exactly the format in which you want the date to be represented. This needs to match the format that Firefox expects to see for this date. The format that is used when automatically converted to text is not the same as is specified for cookies. However, given that Firefox is converting all of the dates it might just work.
Problem 2: You appear to be confusing the concept of an individual cookie vs the entire cookie string. You are wiping out all of the cookies for the domain and replacing them with a single cookie, which is the first one you encounter with an explicitly defined expiration time. This may be OK in your environment if you know there is only one cookie for this domain.
If you are going to set the entire cookie string, you need to build it up from each cookie in that domain. It should only be set once it is complete (after the loop).
Alternately, you can use nsICookieManager2 and deal with each cookie individually. You will then read one, and then add() it (although, the add() method is stated as something of a back door).
Either way, you are currently loosing information by removing any but the first cookie and by dropping potentially additional information from the cookie (e.g. cookie.path, etc.)
Problem 3: Testing in FF32.0.1 indicated that the cookie string interface did not function as expected, at least as far as getCookieString(). That function returned a string in some cases, null in others. When a string was returned it only contained name=value pairs without any expiration information, path, etc. Testing indicated that the nsICookieManager2 interface functioned properly (including verifying that the information was stored in SQLite cookie database).
Note 1: In addition, given how cookie.host is formatted (i.e. it could have a "." as the first character), you may be better off using a regular expression to match the domain against cookie.host, unless you are certain that you know if the extra "." is in the exact domain you are dealing with. (outside the loop):
var domain = "yourdomain.com";
var domainRegex = new RegExp( "\.?" + domain + "$", "i");
(In the loop):
domainRegex.lastIndex = 0; // Clear the Regex.
if(domainRegex.test(cookie.host)) { // check for the current page
Given the issues with the nsICookieService interface, my preference would be to use the nsICookieManager2 interface instead. This also permits dealing with each cookie one at a time. The following code should do what your code appears to be attempting to accomplish (set the expiration time for all cookies in a domain). It is also necessary to use the nsICookie2 interface instead of nsICookie1 due to the need for cookie.isHttpOnly.
I have removed code used for testing, if you want it I can add it back in.
The following does what it appears your code is intended to do (change all cookies for a domain to have a specific expiration time):
Components.utils.import("resource://gre/modules/Services.jsm"); var cookieMgr2 = Services.cookies;
var domain = "zzzzzzzzzzzzzzzzzzzz.com";
var usertime = 600;
var domainRegex = new RegExp( "\.?" + domain + "$", "i");
var expi = new Date(Date.now() + usertime*60000); // how long to stay login
for (var e = cookieMgr2.getCookiesFromHost(domain); e.hasMoreElements();) { //Get an enumerator which only gives hosts that are close to what we want.
var cookie = e.getNext().QueryInterface(Components.interfaces.nsICookie2);;
domainRegex.lastIndex = 0; // Clear the Regex.
if(domainRegex.test(cookie.host)) { // check for current page
//This next line makes the change you appear to desire to each cookie in the domain.
cookieMgr2.add(domain, cookie.path ,cookie.name,cookie.value, cookie.isSecure, cookie.isHttpOnly, false, expi.getTime()); //Make non-session and set exiration time.
}
}
If it is that you are wanting to remove a cookie, then the following should work:
if(domainRegex.test(cookie.host)) { // check for the current page
cookieMgr2.remove(cookie.host,cookie.name,cookie.path, false);
}
Upvotes: 0