I need to access all the cookies from a JavaFX WebView. As far as I can see there's a com.sun.webkit that implements its own CookieManager, Cookie, etc, etc. In that implementation, the cookies are hidden away and there's no way to access them.
Am I correct in thinking there are only two solutions:
- Implement my own CookieManager
- Use reflection to access the internals of CookieManager
Am I missing anything here?
Implementing my own CookieManager is no trivial task. com.sun.webkit's is more than 1500 lines of code.
Using reflection to access the internals is quite horrible. So far, I managed to dump the cookies to a JSON file but look at the code:
private void saveCookies() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException, ClassNotFoundException, IOException {
CookieManager cookieManager = (CookieManager) CookieHandler.getDefault();
Field f = cookieManager.getClass().getDeclaredField("store");
f.setAccessible(true);
Object cookieStore = f.get(cookieManager);
Field bucketsField = Class.forName("com.sun.webkit.network.CookieStore").getDeclaredField("buckets");
bucketsField.setAccessible(true);
Map buckets = (Map) bucketsField.get(cookieStore);
f.setAccessible(true);
Map<String, Collection> cookiesToSave = new HashMap<>();
for (Object o : buckets.entrySet()) {
Map.Entry pair = (Map.Entry) o;
String domain = (String) pair.getKey();
Map cookies = (Map) pair.getValue();
cookiesToSave.put(domain, cookies.values());
}
Gson gson = new GsonBuilder().create();
String json = gson.toJson(cookiesToSave);
System.out.println(json);
Files.write(Paths.get("cookies.json"), json.getBytes());
}
Following @James_D comments, I tried making a wrapper for CookieManager, something like this:
package sample;
import com.sun.webkit.network.CookieManager;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.CookieHandler;
import java.net.URI;
import java.util.*;
public class MyCookieManager extends CookieHandler {
private final CookieManager cookieManager = new CookieManager();
private final Set<URI> uris = new HashSet<>();
MyCookieManager() {
}
@Override
public Map<String, List<String>> get(URI uri, Map<String, List<String>> requestHeaders) throws IOException {
uris.add(uri);
return cookieManager.get(uri, requestHeaders);
}
@Override
public void put(URI uri, Map<String, List<String>> responseHeaders) throws IOException {
uris.add(uri);
cookieManager.put(uri, responseHeaders);
}
void save() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
System.out.println("Saving cookies");
System.out.println(uris);
for (URI uri : uris) {
System.out.println(uri);
System.out.println(cookieManager.get(uri, new HashMap<>()));
}
}
}
After accessing Google, when I call save, I get this:
https://ssl.gstatic.com/gb/images/b_8d5afc09.png
{}
https://www.google.co.uk/images/branding/googlelogo/1x/googlelogo_white_background_color_272x92dp.png
{Cookie=[NID=110=TnISuEnlryFjSzvLgWXIuTBRDx_CTBlgPOqFzCPXM88M0xQY_1nSJEG2uyCxk-RFNbdexuen5A_3CZXHevseXhRSKJmRSHis0pUb4kvFCxliWT8RsKvRXoAxBYJhGGd2]}
https://www.google.co.uk/client_204?&atyp=i&biw=500&bih=455&ei=Q72cWa_IJ4KhUc6xpqAH
{Cookie=[NID=110=TnISuEnlryFjSzvLgWXIuTBRDx_CTBlgPOqFzCPXM88M0xQY_1nSJEG2uyCxk-RFNbdexuen5A_3CZXHevseXhRSKJmRSHis0pUb4kvFCxliWT8RsKvRXoAxBYJhGGd2]}
https://clients1.google.co.uk/generate_204
{Cookie=[NID=110=TnISuEnlryFjSzvLgWXIuTBRDx_CTBlgPOqFzCPXM88M0xQY_1nSJEG2uyCxk-RFNbdexuen5A_3CZXHevseXhRSKJmRSHis0pUb4kvFCxliWT8RsKvRXoAxBYJhGGd2]}
https://www.google.co.uk/xjs/_/js/k=xjs.hp.en_US.HWKnNOqE224.O/m=sb_he,d/am=ABg/rt=j/d=1/t=zcms/rs=ACT90oFd7WTU33BO8_uKNZdqfket_iKTeg
{Cookie=[NID=110=TnISuEnlryFjSzvLgWXIuTBRDx_CTBlgPOqFzCPXM88M0xQY_1nSJEG2uyCxk-RFNbdexuen5A_3CZXHevseXhRSKJmRSHis0pUb4kvFCxliWT8RsKvRXoAxBYJhGGd2]}
https://google.com/
{}
https://www.google.co.uk/?gfe_rd=cr&ei=Q72cWb30H9P38Ae7lKagCw
{Cookie=[NID=110=TnISuEnlryFjSzvLgWXIuTBRDx_CTBlgPOqFzCPXM88M0xQY_1nSJEG2uyCxk-RFNbdexuen5A_3CZXHevseXhRSKJmRSHis0pUb4kvFCxliWT8RsKvRXoAxBYJhGGd2]}
https://www.google.co.uk/images/nav_logo229.png
{Cookie=[NID=110=TnISuEnlryFjSzvLgWXIuTBRDx_CTBlgPOqFzCPXM88M0xQY_1nSJEG2uyCxk-RFNbdexuen5A_3CZXHevseXhRSKJmRSHis0pUb4kvFCxliWT8RsKvRXoAxBYJhGGd2]}
https://ssl.gstatic.com/gb/js/sem_e63c08fa6f0a34d4ef28b1bece13b39d.js
{}
As you can see there's a lot of repetition and I don't have access to a lot of the original information of the cookie. In this case, it should be just one cookie (I think) that looks like this:
{
"google.co.uk": [
{
"name": "NID",
"value": "110\u003dZVaVkKbDxN3aQJYtBTWUQ9G5yc4pGb4TpB4EmTJA9bUB2a27ukBdWh28arRI52lw2Tt9hTtXxLhuWFQl55JaQXUJ3hwQzAFXKI0FB-RCU67MmgvCj9wxgqs9yg7BzBCo",
"expiryTime": 1519255457000,
"domain": "google.co.uk",
"path": "/",
"creationTime": {
"baseTime": 1503444256974,
"subtime": 0
},
"lastAccessTime": 1503444257350,
"persistent": true,
"hostOnly": false,
"secureOnly": false,
"httpOnly": true
}
]
}