Cookie

本文档介绍如何使用 Cookie。

概述 

Fuzio 将 Cookie 的处理委托给 Chromium 引擎(Chromium engine)。Chromium 决定如何从 Web 服务器下载 Cookie、如何从 HTTP 头中提取 Cookie,并将其存储在用户数据目录(User Data directory)(持久性 Cookie)或存储在内存中(会话 Cookie)。

CookieStore 类允许你获取、修改和删除 Cookie。Cookie类提供有关某个具体 Cookie 的信息。

要获取某个指定 ProfileCookieStore,请使用 Profile.cookieStore() 方法。Engine.cookieStore() 方法会返回与默认 profile 关联的 CookieStore

要访问 Cookie 存储,请使用以下方式:

Java
Kotlin
var cookieStore = profile.cookieStore();
val cookieStore = profile.cookieStore()

支持的协议 

Fuzio 支持通过以下协议发送的 Cookie:

  • HTTP
  • HTTPS
  • WS (WebSocket)
  • WSS (Secured WebSocket)

如果 Cookie 是通过不在列表中的协议发送的,例如 ftp://,它将不会被存储到 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,请使用 cookies() 方法:

Java
Kotlin
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() 方法:

Java
Kotlin
cookieStore.cookies("https://html5test.jiku.co")
        .forEach(cookie -> System.out.println("cookie = " + cookie));
cookieStore.cookies("https://html5test.jiku.co")
    .forEach { println("cookie = $it") }

持久性(Persistent) 

要创建一个带有过期时间的持久性 Cookie,请使用以下代码:

Java
Kotlin
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,请使用以下代码:

Java
Kotlin
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,请使用 deleteAll() 方法:

Java
Kotlin
var numberOfDeletedCookies = cookieStore.deleteAll();
cookieStore.persist();
val numberOfDeletedCookies = cookieStore.deleteAll()
cookieStore.persist()

要删除单个 Cookie,请使用 delete(Cookie)。下面的代码会逐个删除所有 Cookie:

Java
Kotlin
cookieStore.cookies().forEach(cookieStore::delete);
cookieStore.persist();
cookieStore.cookies().forEach(cookieStore::delete)
cookieStore.persist()

你可以通过 NetworkCanSetCookieCallbackCanGetCookiesCallback 回调来控制所有入站(incoming)和出站(outgoing)的 Cookie。

要阻止传入的 cookie,请使用以下代码:

Java
Kotlin
network.set(CanSetCookieCallback.class, params ->
        CanSetCookieCallback.Response.cannot()
);
network.register(CanSetCookieCallback {
    CanSetCookieCallback.Response.cannot()
})

要阻止出站 Cookie,请使用以下代码:

Java
Kotlin
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 时通过相应选项手动指定要使用的存储。例如:

Java
Kotlin
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 进行加密。

微信咨询

即库客服

微信公众号二维码

技术客服

微信公众号二维码