Files
2026-07-13 21:36:47 +08:00

495 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: 存储与认证
description: 管理 Cookie、localStorage、sessionStorage、浏览器存储状态,保存与恢复认证,或测试依赖存储的功能
metadata:
type: reference
---
# 存储与认证
> **使用场景**:管理 Cookie、localStorage、sessionStorage、浏览器存储状态,保存与恢复认证,或测试依赖存储的功能。
> **前置条件**[core-commands.md](core-commands.md)——了解基本 CLI 用法
## 快速参考
```bash
# 将所有浏览器状态(Cookie + localStorage)保存到文件
playwright-cli state-save auth.json
# 在新会话中恢复状态
playwright-cli state-load auth.json
# 快速 Cookie 操作
playwright-cli cookie-list
playwright-cli cookie-set session_id abc123 --domain=example.com --httpOnly --secure
playwright-cli cookie-delete session_id
playwright-cli cookie-clear
# localStorage
playwright-cli localstorage-set theme dark
playwright-cli localstorage-get theme
playwright-cli localstorage-clear
# sessionStorage
playwright-cli sessionstorage-set step 3
playwright-cli sessionstorage-get step
playwright-cli sessionstorage-clear
```
## 存储状态(保存与恢复)
最强大的功能——将整个浏览器状态(所有来源的 Cookie + localStorage)保存到一个 JSON 文件中,之后恢复该状态以跳过登录流程。
### 保存存储状态
```bash
# 保存到自动生成的文件名(storage-state-{timestamp}.json
playwright-cli state-save
# 保存到指定文件
playwright-cli state-save auth.json
playwright-cli state-save ./states/admin-session.json
```
### 恢复存储状态
```bash
# 从文件加载状态
playwright-cli state-load auth.json
# 加载后导航——Cookie 和 localStorage 已设置好
playwright-cli goto https://app.example.com/dashboard
# 已通过认证!
```
### 存储状态文件格式
保存的 JSON 同时包含 Cookie 和 localStorage
```json
{
"cookies": [
{
"name": "session_id",
"value": "abc123",
"domain": "example.com",
"path": "/",
"expires": 1735689600,
"httpOnly": true,
"secure": true,
"sameSite": "Lax"
}
],
"origins": [
{
"origin": "https://example.com",
"localStorage": [
{ "name": "theme", "value": "dark" },
{ "name": "user_id", "value": "12345" },
{ "name": "auth_token", "value": "jwt.token.here" }
]
}
]
}
```
## 认证模式
最常用的工作流程——登录一次,保存状态,跨会话复用。
### 步骤 1:登录并保存
```bash
playwright-cli open https://app.example.com/login
playwright-cli snapshot
playwright-cli fill e1 "admin@example.com"
playwright-cli fill e2 "secure-password"
playwright-cli click e3
# 等待重定向以确认登录成功
playwright-cli run-code "async page => {
await page.waitForURL('**/dashboard');
return 'Login successful: ' + page.url();
}"
# 保存已认证的状态
playwright-cli state-save auth.json
playwright-cli close
```
### 步骤 2:复用认证状态
```bash
# 新会话——完全跳过登录
playwright-cli open https://app.example.com
playwright-cli state-load auth.json
playwright-cli goto https://app.example.com/dashboard
# 已以管理员身份登录!
playwright-cli snapshot # 查看仪表盘
```
### 多角色认证
```bash
# 为每个角色保存状态
playwright-cli open https://app.example.com/login
playwright-cli fill e1 "admin@example.com"
playwright-cli fill e2 "admin-pass"
playwright-cli click e3
playwright-cli state-save admin-auth.json
playwright-cli close
playwright-cli open https://app.example.com/login
playwright-cli fill e1 "user@example.com"
playwright-cli fill e2 "user-pass"
playwright-cli click e3
playwright-cli state-save user-auth.json
playwright-cli close
# 现在使用它们
playwright-cli -s=admin open https://app.example.com
playwright-cli -s=admin state-load admin-auth.json
playwright-cli -s=admin goto https://app.example.com/admin
playwright-cli -s=user open https://app.example.com
playwright-cli -s=user state-load user-auth.json
playwright-cli -s=user goto https://app.example.com/profile
```
### OAuth / SSO 认证
针对涉及重定向和弹出窗口的 OAuth 流程:
```bash
playwright-cli run-code "async page => {
await page.goto('https://app.example.com/login');
// 点击"使用 Google 登录"
const [popup] = await Promise.all([
page.waitForEvent('popup'),
page.click('button:text(\"Login with Google\")')
]);
// 在弹出窗口中填写凭据
await popup.fill('input[type=email]', 'user@gmail.com');
await popup.click('#identifierNext');
await popup.fill('input[type=password]', 'password');
await popup.click('#passwordNext');
// 等待弹出窗口关闭且主页面完成重定向
await popup.waitForEvent('close');
await page.waitForURL('**/dashboard');
// 保存已认证状态
await page.context().storageState({ path: 'oauth-auth.json' });
return 'OAuth login complete';
}"
```
## Cookies
### 列出所有 Cookie
```bash
playwright-cli cookie-list
```
### 按域名筛选
```bash
playwright-cli cookie-list --domain=example.com
```
### 按路径筛选
```bash
playwright-cli cookie-list --path=/api
```
### 获取指定 Cookie
```bash
playwright-cli cookie-get session_id
playwright-cli cookie-get __cf_bm
```
### 设置 Cookie
```bash
# 基础 Cookie
playwright-cli cookie-set session abc123
# 带完整选项的 Cookie
playwright-cli cookie-set session abc123 \
--domain=example.com \
--path=/ \
--httpOnly \
--secure \
--sameSite=Lax
# 带过期时间的 Cookie(Unix 时间戳)
playwright-cli cookie-set remember_me token123 --expires=1735689600
```
### 删除 Cookie
```bash
playwright-cli cookie-delete session_id
playwright-cli cookie-delete __cf_bm
```
### 清除所有 Cookie
```bash
playwright-cli cookie-clear
```
### 高级:一次设置多个 Cookie
```bash
playwright-cli run-code "async page => {
await page.context().addCookies([
{
name: 'session_id',
value: 'sess_abc123',
domain: 'example.com',
path: '/',
httpOnly: true,
secure: true,
sameSite: 'Strict'
},
{
name: 'preferences',
value: JSON.stringify({ theme: 'dark', lang: 'en' }),
domain: 'example.com',
path: '/'
},
{
name: 'tracking_opt_out',
value: 'true',
domain: '.example.com',
path: '/'
}
]);
}"
```
### 高级:编程方式读取所有 Cookie
```bash
playwright-cli run-code "async page => {
const cookies = await page.context().cookies();
return cookies.map(c => ({
name: c.name,
value: c.value.substring(0, 20) + '...',
domain: c.domain,
httpOnly: c.httpOnly,
secure: c.secure,
expires: new Date(c.expires * 1000).toISOString()
}));
}"
```
## Local Storage
### 列出所有项目
```bash
playwright-cli localstorage-list
```
### 获取值
```bash
playwright-cli localstorage-get theme
playwright-cli localstorage-get auth_token
```
### 设置值
```bash
playwright-cli localstorage-set theme dark
playwright-cli localstorage-set language en-US
# 设置 JSON 值(对 JSON 加引号)
playwright-cli localstorage-set user_settings '{"theme":"dark","fontSize":14,"sidebar":true}'
```
### 删除项目
```bash
playwright-cli localstorage-delete auth_token
```
### 清除所有
```bash
playwright-cli localstorage-clear
```
### 高级:批量操作
```bash
playwright-cli run-code "async page => {
await page.evaluate(() => {
localStorage.setItem('token', 'jwt_abc123');
localStorage.setItem('user_id', '12345');
localStorage.setItem('user_name', 'Jane Doe');
localStorage.setItem('preferences', JSON.stringify({
theme: 'dark',
notifications: true,
language: 'en'
}));
localStorage.setItem('onboarding_complete', 'true');
});
}"
```
### 高级:读取所有 localStorage
```bash
playwright-cli run-code "async page => {
return await page.evaluate(() => {
const items = {};
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
items[key] = localStorage.getItem(key);
}
return items;
});
}"
```
## Session Storage
Session storage 按标签页隔离,关闭标签页时自动清除。
### 列出所有项目
```bash
playwright-cli sessionstorage-list
```
### 获取 / 设置 / 删除
```bash
playwright-cli sessionstorage-get form_step
playwright-cli sessionstorage-set form_step 3
playwright-cli sessionstorage-set form_data '{"name":"Jane","email":"jane@example.com"}'
playwright-cli sessionstorage-delete form_step
playwright-cli sessionstorage-clear
```
## IndexedDB
IndexedDB 需要通过 `run-code` 进行访问:
### 列出数据库
```bash
playwright-cli run-code "async page => {
return await page.evaluate(async () => {
const databases = await indexedDB.databases();
return databases.map(db => ({ name: db.name, version: db.version }));
});
}"
```
### 删除数据库
```bash
playwright-cli run-code "async page => {
await page.evaluate(dbName => {
indexedDB.deleteDatabase(dbName);
}, 'myDatabase');
return 'Database deleted';
}"
```
### 从对象存储中读取数据
```bash
playwright-cli run-code "async page => {
return await page.evaluate(() => {
return new Promise((resolve, reject) => {
const request = indexedDB.open('myDatabase');
request.onsuccess = () => {
const db = request.result;
const tx = db.transaction('myStore', 'readonly');
const store = tx.objectStore('myStore');
const getAll = store.getAll();
getAll.onsuccess = () => resolve(getAll.result);
getAll.onerror = () => reject(getAll.error);
};
request.onerror = () => reject(request.error);
});
});
}"
```
## 常见模式
### Token 刷新测试
```bash
# 设置一个已过期的 Token 以测试刷新逻辑
playwright-cli localstorage-set auth_token "expired-jwt-token"
playwright-cli localstorage-set token_expiry "1609459200"
# 导航以触发 Token 刷新
playwright-cli goto https://app.example.com/dashboard
# 检查 Token 是否已刷新
playwright-cli localstorage-get auth_token
```
### 功能开关测试
```bash
# 通过 localStorage 启用功能开关
playwright-cli localstorage-set feature_flags '{"newCheckout":true,"darkMode":true,"betaFeatures":false}'
# 重新加载以生效
playwright-cli reload
playwright-cli snapshot
```
### 清除所有内容,从头开始
```bash
playwright-cli cookie-clear
playwright-cli localstorage-clear
playwright-cli sessionstorage-clear
playwright-cli reload
```
### 保存与恢复的完整流程
```bash
# 手动设置状态
playwright-cli open https://example.com
playwright-cli cookie-set session abc123 --domain=example.com
playwright-cli localstorage-set user john
playwright-cli localstorage-set theme dark
# 保存所有内容
playwright-cli state-save my-session.json
# 之后——在新会话中恢复状态
playwright-cli open https://example.com
playwright-cli state-load my-session.json
playwright-cli reload
# Cookie 和 localStorage 已恢复
```
## 安全注意事项
- **切勿提交认证状态文件**——将 `*.auth-state.json``auth.json` 添加到 `.gitignore`
- **使用后删除状态文件**——自动化完成后执行 `rm auth.json`
- **使用环境变量保存凭据**——绝不在脚本中硬编码密码
- **内存会话更安全**——默认会话不会持久化到磁盘,降低了暴露风险
- **轮换已保存的状态**——认证 Token 会过期;请定期重新生成状态文件
- **避免在共享机器上保存状态**——存储状态文件包含会话 Token 和个人数据