这个结构体(struct PasswordForm
)是 Chromium 浏览器(以及所有基于 Chromium 的浏览器,例如 Chrome、Edge 等)中密码管理器用来存储和管理单个登录凭证(即一组用户名和密码)的核心数据结构。它不仅包含了用户名和密码本身,还包含了大量关于该凭证的来源、上下文、元数据以及在网页表单中定位所需的信息。
🔑 枚举类型 (Enums) 解释
PasswordForm
结构体内部定义了四个重要的枚举类型,用于对表单和凭证进行分类和标记。
1. enum class Scheme
(认证方案)
用于区分登录凭证的认证方式或来源。只有具有相同 Scheme
的 PasswordForm
才能相互匹配和自动填充。
成员 |
含义 |
备注 |
kHtml |
HTML 表单认证(默认) |
最常见的网页登录表单。 |
kBasic |
HTTP Basic 认证对话框 |
浏览器弹出的基础认证窗口。 |
kDigest |
HTTP Digest 认证对话框 |
浏览器弹出的摘要认证窗口。 |
kOther |
其他类型的认证方案。 |
通用或未知方案。 |
kUsernameOnly |
仅包含用户名的凭证。 |
仅保存用户名的场景。 |
2. enum class Type
(凭证类型)
用于区分凭证的创建或获取方式,这个值会被转换成整数并存储在密码后端,因此其数值是固定的。
成员 |
数值 |
含义 |
kFormSubmission |
0 |
通过用户提交网页表单保存的凭证(最常见)。 |
kGenerated |
1 |
由密码管理器自动生成并保存的密码。 |
kApi |
2 |
通过 Credential Management API 存储的凭证。 |
kManuallyAdded |
3 |
用户在设置界面中手动添加的凭证。 |
kImported |
4 |
从其他来源导入的凭证。 |
kReceivedViaSharing |
5 |
通过密码分享功能接收到的凭证。 |
kImportedViaCredentialExchange |
6 |
通过凭证交换机制导入。 |
kChangeSubmission |
7 |
用户修改密码后保存的凭证。 |
3. enum class GenerationUploadStatus
(生成上传状态)
跟踪关于密码生成的信息是否已发送到服务器。
成员 |
含义 |
kNoSignalSent |
未向服务器发送信号。 |
kPositiveSignalSent |
发送了积极信号(例如:用户使用了生成的密码)。 |
kNegativeSignalSent |
发送了消极信号(例如:用户没有使用生成的密码)。 |
4. enum class MatchType
(匹配类型)
这是一个位掩码(bitmask),用于描述 PasswordForm
如何与当前页面的表单或 URL 进行匹配,一个凭证可以有多种匹配类型。
成员 |
值 |
含义 |
kExact |
0 |
精确匹配:凭证的 signon_realm 与请求的 URL 完全一致。 |
kAffiliated |
1 << 1 (2 ) |
关联匹配:通过关联服务(Affiliation Service)判断,signon_realm 与 URL 属于同一组关联网站。 |
kPSL |
1 << 2 (4 ) |
公共后缀列表匹配(Public Suffix List):signon_realm 与 URL 具有相同的 eTLD+1(effective Top-Level Domain + 1,例如 example.com )。 |
kGrouped |
1 << 3 (8 ) |
分组匹配:通过分组信息判断,signon_realm 与 URL 属于同一组。 |
5. enum class Store
(存储位置)
指示凭证存储的位置,它也是一个位掩码,一个凭证可能同时存在于两个存储中。
成员 |
值 |
含义 |
kNotSet |
0 |
未设置(默认值)。 |
kProfileStore |
1 << 0 (1 ) |
本地配置文件存储:凭证存储在本地设备。 |
kAccountStore |
1 << 1 (2 ) |
账户存储:凭证存储在与 Google 账户同步的云端存储中。 |
📊 核心数据字段 (Core Fields) 解释
这些字段是识别和定位凭证在数据库中的位置,以及在网页上进行自动填充的关键信息。
1. 身份和定位 (Identity & Location)
字段 |
类型 |
作用和重要性 |
primary_key |
std::optional<FormPrimaryKey> |
数据库中的主键,仅当从数据库读取时设置,用于唯一标识数据库记录。 |
scheme |
Scheme |
认证方案(来自上面的枚举),默认是 kHtml 。 |
signon_realm |
std::string |
登录域/范围。对于 HTML 表单,它通常是 scheme://host:port 。对于对话框,包含 HTTP Realm。它实际上是检索数据的“主键”。 |
url |
GURL |
表单所在页面的 URL (scheme , host , port , path )。密码管理器用它来决定哪个凭证适合当前页面(最长前缀匹配)。 |
action |
GURL |
表单提交的 URL(即 <form action="..."> 中的值)。这是自动填充的主要数据,保存的凭证的 action 必须与页面表单的 action 匹配才能自动填充。如果为空,则采用受限的自动填充策略(等待用户输入用户名)。 |
2. 用户名和密码 (Username & Password)
字段 |
类型 |
作用和重要性 |
username_element |
std::u16string |
用户名输入框的 name 属性。 |
username_value |
std::u16string |
实际保存的用户名。 |
password_element |
std::u16string |
当前密码输入框的 name 属性。 |
password_value |
std::u16string |
实际保存的当前密码。非空是凭证可以持久化到密码存储的必要条件。 |
new_password_element |
std::u16string |
新密码输入框的 name 属性(用于注册或修改密码表单)。不持久化。 |
new_password_value |
std::u16string |
实际保存的新密码(不持久化)。 |
all_alternative_usernames |
AlternativeElementVector |
所有可能的备选用户名,用于填充下拉列表。 |
all_alternative_passwords |
AlternativeElementVector |
所有可能的备选密码(用于待定密码状态)。 |
keychain_identifier |
std::string |
钥匙串标识符(仅在 iOS 上使用)。 |
字段 |
类型 |
作用和重要性 |
date_last_used |
base::Time |
上次使用此登录凭证的日期。 |
date_password_modified |
base::Time |
上次修改密码值的日期。旧凭证可能为空。 |
date_created |
base::Time |
登录信息被 Chrome 保存的日期。 |
blocked_by_user |
bool |
用户是否选择了永不记住此站点的密码。 |
type |
Type |
凭证类型(来自上面的枚举),默认是 kFormSubmission 。 |
times_used_in_html_form |
int |
此用户名/密码在 HTML 表单中使用的次数。 |
in_store |
Store |
凭证存在于哪个或哪些存储中(本地或账户同步)。 |
password_issues |
base::flat_map<...> |
凭证的安全问题(例如泄露、钓鱼)及其元数据。 |
notes |
std::vector<PasswordNote> |
附加到凭证的笔记。 |
4. Android 和关联信息 (Android & Affiliation)
这些字段主要用于关联桌面浏览器密码和 Android 应用密码。
字段 |
类型 |
作用和重要性 |
affiliated_web_realm |
std::string |
如果是 Android 凭证,这是关联的网页域。 |
app_display_name |
std::u16string |
如果是 Android 凭证,这是应用的显示名称(如 Play 商店名称)。 |
app_icon_url |
GURL |
如果是 Android 凭证,这是应用图标的 URL。 |
5. Credential Management API 和 WebAuthn (凭证管理 API)
字段 |
类型 |
作用和重要性 |
display_name |
std::u16string |
用户友好的名称(由 Credential Management API 设置)。 |
icon_url |
GURL |
用于在 UI 中显示的凭证图标 URL(如用户头像)。 |
federation_origin |
url::SchemeHostPort |
身份提供者(Federated Login,如“使用 Google 登录”)的来源。 |
skip_zero_click |
bool |
如果为 true ,Chrome 不会在没有用户交互的情况下将此凭证返回给站点。 |
accepts_webauthn_credentials |
bool |
表单是否可以填充 WebAuthn 凭证。 |
6. 密码分享信息 (Password Sharing)
字段 |
类型 |
作用和重要性 |
sender_email |
std::u16string |
共享此密码的发送者邮箱。 |
sender_name |
std::u16string |
共享此密码的发送者姓名。 |
sender_profile_image_url |
GURL |
发送者的个人资料图片 URL。 |
date_received |
base::Time |
通过分享功能接收此密码的日期。 |
sharing_notification_displayed |
bool |
是否已向用户展示分享通知。 |
🛠️ 方法 (Methods) 解释
结构体包含了一系列判断表单类型的辅助方法和访问器。这些方法通常基于表单中不同元素的组合(如是否同时存在当前密码和新密码字段)来推断表单的用途。
方法 |
作用 |
IsLikelyLoginForm() |
基于启发式规则判断是否为登录表单(有用户名、密码,无新密码)。 |
IsLikelySignupForm() |
基于启发式规则判断是否为注册表单(有用户名、新密码,无当前密码)。 |
IsLikelyChangePasswordForm() |
基于启发式规则判断是否为修改密码表单(有当前密码,有新密码)。 |
IsLikelyResetPasswordForm() |
基于启发式规则判断是否为重置密码表单(有新密码,无当前密码或用户名)。 |
GetPasswordFormType() |
返回表单的分类类型(更细致的分类)。 |
HasUsernameElement() / HasPasswordElement() / HasNewPasswordElement() |
检查对应的输入元素是否存在。 |
IsFederatedCredential() |
检查 federation_origin 是否非空(是否为联合登录凭证)。 |
IsSingleUsername() |
检查是否仅有用户名元素而没有密码或新密码元素。 |
IsUsingAccountStore() / IsUsingProfileStore() |
检查凭证是否存储在账户或配置文件存储中。 |
HasNonEmptyPasswordValue() |
检查 password_value 或 new_password_value 是否非空。 |
struct PasswordForm
是 Chromium 密码管理器中存储一个登录实体的全面记录。它是一个高度工程化的结构,旨在支持多种认证方式(HTML、Basic/Digest)、多种凭证来源(提交、生成、API、导入)、跨平台(桌面、Android)的关联以及复杂的自动填充和密码安全检查逻辑。简单来说,它就是密码管理器中的一个“密码卡片”,但包含的元数据远超卡片本身所展示的内容。