Cookie
本文档介绍如何使用 Cookie。
概述
Fuzio 将 Cookie 的处理委托给 Chromium 引擎(Chromium engine)。Chromium 决定如何从 Web 服务器下载 Cookie、如何从 HTTP 头中提取 Cookie,并将其存储在用户数据目录(User Data directory)(持久性 Cookie)或存储在内存中(会话 Cookie)。
CookieStore 类允许你获取、修改和删除 Cookie。Cookie类提供有关某个具体 Cookie 的信息。
要获取某个指定 Profile 的 CookieStore,请使用 Profile.cookieStore() 方法。Engine.cookieStore() 方法会返回与默认 profile 关联的 CookieStore。
要访问 Cookie 存储,请使用以下方式:
var cookieStore = profile.cookieStore();
val cookieStore = profile.cookieStore()
支持的协议
Fuzio 支持通过以下协议发送的 Cookie:
- HTTP
- HTTPS
- WS (WebSocket)
- WSS (Secured WebSocket)
如果 Cookie 是通过不在列表中的协议发送的,例如 ftp://,它将不会被存储到 Cookie 存储中。
使用 Cookie
Fuzio 支持以下类型的 Cookie:
- Persistent cookies(持久性 Cookie) — 存储在 Chromium 的用户数据目录中。如果你删除 Chromium 的用户数据目录,所有持久性 Cookie 都会被移除。
- Session cookies(会话 Cookie) — 存储在应用程序内存中。当应用程序终止时,这些 Cookie 会被自动移除。
- Secure cookies(安全 Cookie) — 只能通过加密连接(即 HTTPS)进行传输。这使得 Cookie 更不容易在被窃听时遭到窃取。
- HttpOnly cookies — 无法被客户端 API(例如 JavaScript)访问。该限制可以消除通过跨站脚本攻击(XSS)进行 Cookie 窃取的威胁。不过,该 Cookie 仍可能受到跨站跟踪(XST)和跨站请求伪造(XSRF)攻击的影响。
当你修改 Cookie 后,请使用 CookieStore.persist() 方法来保存更改。
获取 Cookie
要获取所有 Cookie,请使用 cookies() 方法:
cookieStore.cookies().forEach(cookie -> {
var name = cookie.name();
var value = cookie.value();
var domain = cookie.domain();
var path = cookie.path();
var secure = cookie.isSecure();
var sameSite = cookie.sameSite();
var httpOnly = cookie.isHttpOnly();
var partitionKey = cookie.partitionKey();
var creationTime = cookie.creationTime();
var expirationTime = cookie.expirationTime();
});
cookieStore.cookies().forEach {
val name = it.name()
val value = it.value()
val domain = it.domain()
val path = it.path()
val secure = it.isSecure
val sameSite = it.sameSite()
val httpOnly = it.isHttpOnly
val partitionKey = it.partitionKey()
val creationTime = it.creationTime()
val expirationTime = it.expirationTime()
}
要按 URL 获取所有 Cookie,请使用接收字符串参数的 cookies() 方法:
cookieStore.cookies("https://html5test.jiku.co")
.forEach(cookie -> System.out.println("cookie = " + cookie));
cookieStore.cookies("https://html5test.jiku.co")
.forEach { println("cookie = $it") }
创建 Cookie
持久性(Persistent)
要创建一个带有过期时间的持久性 Cookie,请使用以下代码:
cookieStore.set(Cookie.newBuilder("https://www.baidu.com/")
.creationTime(creationTime)
.expirationTime(expirationTime)
.name("name")
.value("value")
.path("/")
.build()
);
cookieStore.persist();
val cookie = Cookie(
domain = "https://www.baidu.com/",
creationTime = creationTime,
expirationTime = expirationTime,
name = "name",
value = "value",
path = "/"
)
cookieStore.set(cookie)
cookieStore.persist()
会话(Session)
要创建一个会话 Cookie,请使用以下代码:
cookieStore.set(Cookie.newBuilder("https://www.baidu.com/")
.name("name")
.value("value")
.path("/")
.build()
);
cookieStore.persist();
val cookie = Cookie(
domain = "https://www.baidu.com/",
name = "name",
value = "value",
path = "/"
)
cookieStore.set(cookie)
cookieStore.persist()
删除 Cookie
要删除所有 Cookie,请使用 deleteAll() 方法:
var numberOfDeletedCookies = cookieStore.deleteAll();
cookieStore.persist();
val numberOfDeletedCookies = cookieStore.deleteAll()
cookieStore.persist()
要删除单个 Cookie,请使用 delete(Cookie)。下面的代码会逐个删除所有 Cookie:
cookieStore.cookies().forEach(cookieStore::delete);
cookieStore.persist();
cookieStore.cookies().forEach(cookieStore::delete)
cookieStore.persist()
阻止 Cookie
你可以通过 Network 的 CanSetCookieCallback 和 CanGetCookiesCallback 回调来控制所有入站(incoming)和出站(outgoing)的 Cookie。
要阻止传入的 cookie,请使用以下代码:
network.set(CanSetCookieCallback.class, params ->
CanSetCookieCallback.Response.cannot()
);
network.register(CanSetCookieCallback {
CanSetCookieCallback.Response.cannot()
})
要阻止出站 Cookie,请使用以下代码:
network.set(CanGetCookiesCallback.class, params ->
CanGetCookiesCallback.Response.cannot()
);
network.register(CanGetCookiesCallback {
CanGetCookiesCallback.Response.cannot()
})
加密
Fuzio 默认支持 Cookie 加密。它使用 Chromium 的 Cookie 加密机制,因此 Cookie 的存储方式与 Chromium 完全一致。
Linux
在 Linux 上,Fuzio 使用 GNOME Keyring 或 KWallet 来加密 Cookie。该库会自动选择要使用的存储。你也可以在构造 Engine 时通过相应选项手动指定要使用的存储。例如:
var engine = Engine.newInstance(
EngineOptions.newBuilder(renderingMode)
.passwordStore(PasswordStore.GNOME_KEYRING)
.build()
);
val engine = Engine(renderingMode) {
passwordStore = PasswordStore.GNOME_KEYRING
}
Windows
在 Windows 上,Fuzio 仅使用 DPAPI 来加密 Cookie。目前没有其他替代方案。
macOS
在 macOS 上,Fuzio 使用 Keychain 应用中存储的私钥,通过 AES 加密来对 Cookie 进行加密。

