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 存储,请使用以下方式:

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()

你可以通过 Network 的 CanSetCookieCallback 和 CanGetCookiesCallback 回调来控制所有入站(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 进行加密。

更多使用案例 

如果本指南中未涵盖你的使用场景,请参考以下示例:

微信咨询

即库客服

微信公众号二维码

技术客服

微信公众号二维码