# @atproto/lex-password-session 中文文档

规范地址：https://npmcn.com/package/%40atproto/lex-password-session/

版本：0\.3\.2
npm 元数据更新时间：2026-11-06T01:45:24.805Z
中文译文更新时间：2026-11-07T03:53:54.792Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40atproto/lex-password-session
原文对照：https://npmcn.com/package/%40atproto/lex-password-session/?lang=original
项目主页：https://atproto.com/
源码仓库：https://github.com/bluesky-social/atproto

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：162 kB，76 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=22
- 运行依赖：3 个
- 首次发布：2026-01-08T17:10:13.761Z
- 最新版本发布：2026-11-06T01:45:24.299Z
- 近 30 天下载量：43353（2026-10-07 至 2026-11-05，npm 官方下载统计）
- 已发布版本数：47（近 12 个月 47 个）

## 中文简介

基于密码的AT Lexicons客户端认证

## 安装

```sh
npm install @atproto/lex-password-session
```

也可以使用：`pnpm add @atproto/lex-password-session`、`yarn add @atproto/lex-password-session`、`bun add @atproto/lex-password-session`

## README

# @ atproto/ lex- password- session

基于密码的AT协议 Lexicons会话认证. 见 [更改日志](https://npmcn.com/package/%40atproto/lex-password-session/CHANGELOG.md) 用于版本历史.

```bash
npm install @atproto/lex-password-session
```

-   自动更新的会话管理
-   持续和监测会话状态的钩子
-   PDS 从 DD 文档中发现端点
-   双要素认证支持

> \[大
> 
> 此软件包目前处于 **预览**. API 和特性在稳定发布前会有所改变.

**这是什么?**

`@atproto/lex-password-session` 页:1 `PasswordSession` 类 `Agent` 界面从 `@atproto/lex-client`它与AT 协议服务处理基于密码的认证,包括:

1.  创建带有用户名/密码证书的会话
2.  访问令牌过期时自动刷新令牌
3.  通过生命周期钩的会话持久性
4.  使用服务器侧会话清理的优雅登录

```typescript
import { Client } from '@atproto/lex-client'
import { PasswordSession } from '@atproto/lex-password-session'
import * as app from './lexicons/app.js'

// Login with credentials
const session = await PasswordSession.login({
  service: 'https://bsky.social',
  identifier: 'alice.bsky.social',
  password: 'app-password',
  onUpdated: (data) => saveToStorage(data),
  onDeleted: (data) => clearStorage(data.did),
})

const client = new Client(session)

// Make authenticated requests
const profile = await client.call(app.bsky.actor.getProfile, {
  actor: session.did,
})
```

-   [快速启动](https://npmcn.com/package/%40atproto/lex-password-session/#readme-quick-start)
-   [密码会议](https://npmcn.com/package/%40atproto/lex-password-session/#readme-passwordsession)
    -   [登录](https://npmcn.com/package/%40atproto/lex-password-session/#readme-login)
    -   [双向认证](https://npmcn.com/package/%40atproto/lex-password-session/#readme-two-factor-authentication)
    -   [复会](https://npmcn.com/package/%40atproto/lex-password-session/#readme-resume-session)
    -   [注销](https://npmcn.com/package/%40atproto/lex-password-session/#readme-logout)
    -   [静态删除](https://npmcn.com/package/%40atproto/lex-password-session/#readme-static-delete)
    -   [创建账户](https://npmcn.com/package/%40atproto/lex-password-session/#readme-create-account)
-   [会话钩](https://npmcn.com/package/%40atproto/lex-password-session/#readme-session-hooks)
    -   [已更新](https://npmcn.com/package/%40atproto/lex-password-session/#readme-onupdated)
    -   [更新失败](https://npmcn.com/package/%40atproto/lex-password-session/#readme-onupdatefailure)
    -   [已删除](https://npmcn.com/package/%40atproto/lex-password-session/#readme-ondeleted)
    -   [已删除失败](https://npmcn.com/package/%40atproto/lex-password-session/#readme-ondeletefailure)
-   [会话数据](https://npmcn.com/package/%40atproto/lex-password-session/#readme-session-data)
-   [处理错误](https://npmcn.com/package/%40atproto/lex-password-session/#readme-error-handling)
-   [使用客户端](https://npmcn.com/package/%40atproto/lex-password-session/#readme-using-with-client)
-   [许可证](https://npmcn.com/package/%40atproto/lex-password-session/#readme-license)

## 快速启动

**1\. 安装软件包**

```bash
npm install @atproto/lex-password-session @atproto/lex-client
```

**2\. 登录和提出请求**

```typescript
import { Client } from '@atproto/lex-client'
import { PasswordSession } from '@atproto/lex-password-session'

const session = await PasswordSession.login({
  service: 'https://bsky.social',
  identifier: 'your-handle.bsky.social',
  password: 'your-app-password',
})

const client = new Client(session)

// Make authenticated API calls
console.log('Logged in as:', session.did)
```

## 密码会议

这个 `PasswordSession` 类管理基于密码的认证会话.

### 登录

创建一个带有用户名和密码的新会话 :

```typescript
import { PasswordSession } from '@atproto/lex-password-session'

const session = await PasswordSession.login({
  service: 'https://bsky.social',
  identifier: 'alice.bsky.social', // handle or email
  password: 'app-password',
  onUpdated: (data) => {
    // Persist session for later restoration
    localStorage.setItem('session', JSON.stringify(data))
  },
  onDeleted: () => {
    localStorage.removeItem('session')
  },
})

console.log('Logged in as:', session.did)
```

这个 `login()` 方法投出失败。 对于像无效证书这样的预期错误, a `XrpcResponseError` 被抛出。 关于2FA需求,a `LexAuthFactorError` 被抛出.

### 双向认证

> \[叹息\]
> 
> 二要素认证仅适用于使用 **主账户证书**,这是 **强烈反对**密码认证 [应用程序密码](https://bsky.app/settings/app-passwords) 仅仅因为它们是为程序访问(机器人,脚本,CLI工具)而设计的. 对于用户化应用程序,请通过 OAuth 使用 [@atproto/oauth-客户端](https://npmcn.com/oauth/oauth-client) 提供更好的安全和用户控制.

如果账户启用了 2FA , 登录将丢入 `LexAuthFactorError`数字 :

```typescript
import {
  PasswordSession,
  LexAuthFactorError,
} from '@atproto/lex-password-session'

async function loginWith2FA(
  identifier: string,
  password: string,
  authFactorToken?: string,
): Promise<PasswordSession> {
  try {
    return await PasswordSession.login({
      service: 'https://bsky.social',
      identifier,
      password,
      authFactorToken,
      onUpdated: (data) => saveToStorage(data),
      onDeleted: (data) => removeFromStorage(data.did),
    })
  } catch (err) {
    if (err instanceof LexAuthFactorError && !authFactorToken) {
      // 2FA required - prompt user for code
      const token = await promptUserFor2FACode(err.message)
      return loginWith2FA(identifier, password, token)
    }
    throw err
  }
}
```

### 复会

恢复先前保存的会话 :

```typescript
import { PasswordSession, SessionData } from '@atproto/lex-password-session'

// Load session from storage
const savedSession: SessionData = JSON.parse(localStorage.getItem('session')!)

// Resume the session (automatically refreshes tokens)
const session = await PasswordSession.resume(savedSession, {
  onUpdated: (data) => {
    localStorage.setItem('session', JSON.stringify(data))
  },
  onDeleted: () => {
    localStorage.removeItem('session')
  },
})

console.log('Session resumed for:', session.did)

// Access session properties
console.log(session.did) // User's DID
console.log(session.handle) // User's handle
console.log(session.destroyed) // false (session is active)
```

> \[注\]
> 
> `resume()` 自动调用 `refresh()` ,以确保会话是有效的,符号是时空的.

### 注销

结束会话并通知服务器 :

```typescript
await session.logout()
```

登录后 :

-   这个 `onDeleted` 钩子叫做
-   会议被标记为被销毁(第2段)`session.destroyed === true`(中文(简体) )
-   将提出进一步的请求 `'Logged out'`

### 静态删除

删除会话而不创建会话实例:

```typescript
import { PasswordSession, SessionData } from '@atproto/lex-password-session'

const data: SessionData = JSON.parse(localStorage.getItem('session')!)

// Delete the session on the server
await PasswordSession.delete(data)
```

在不需要提出额外请求的情况下,这对清理情景有用.

### 创建账户

创建新账户并获得认证的会话 :

```typescript
import { PasswordSession } from '@atproto/lex-password-session'

const session = await PasswordSession.createAccount(
  {
    handle: 'alice.bsky.social',
    email: 'alice@example.com',
    password: 'secure-password',
  },
  {
    service: 'https://bsky.social',
    onUpdated: (data) => saveToStorage(data),
    onDeleted: (data) => removeFromStorage(data.did),
  },
)

console.log('Account created:', session.did)
```

## 会话钩

Hooks为会话生命周期活动提供回调. 所有钩子收到会话实例为 `this` 上下文.

### 已更新

当会话成功创建或刷新时调用 :

```typescript
const session = await PasswordSession.login({
  service: 'https://bsky.social',
  identifier: 'alice.bsky.social',
  password: 'app-password',
  onUpdated(data) {
    // `this` is the PasswordSession instance
    console.log('Session updated for:', this.did)

    // Persist the updated session
    saveSession(data)
  },
})
```

> \[大
> 
> 请求被封锁时 `onUpdated` 正在运行。 保持这个回调速度以避免延误.

### 更新失败

因瞬态错误( 网络问题, 服务器无法使用) , 令牌刷新失败时调用 :

```typescript
{
  onUpdateFailure(data, error) {
    console.warn('Token refresh failed:', error.message)
    // Session may still be valid - consider retry logic
  }
}
```

### 已删除

当会话终止时调用( 日志或服务器侧无效) :

```typescript
{
  onDeleted(data) {
    console.log('Session ended for:', data.did)
    clearPersistedSession(data.did)
    redirectToLogin()
  }
}
```

### 已删除失败

因瞬间出错无法登录时调用 :

```typescript
{
  onDeleteFailure(data, error) {
    console.error('Logout failed:', error.message)
    // Consider queuing for retry to avoid orphaned sessions
    queueLogoutRetry(data)
  }
}
```

> \[尖叫声\]
> 
> 忽略删除失败可以让会话在服务器上活动. 执行安全敏感应用程序的重试逻辑.

## 会话数据

这个 `SessionData` 类型包含认证和恢复会话所需的全部数据 :

```typescript
type SessionData = {
  // Session credentials and user info from createSession response
  accessJwt: string
  refreshJwt: string
  did: string
  handle: string
  email?: string
  emailConfirmed?: boolean
  didDoc?: object
  // ... other fields from createSession

  // Original service URL used for login
  service: string
}
```

## 处理错误

这个 `PasswordSession` 类使用基于例外的错误处理 :

```typescript
import {
  PasswordSession,
  LexAuthFactorError,
} from '@atproto/lex-password-session'
import { XrpcResponseError } from '@atproto/lex-client'

try {
  const session = await PasswordSession.login({
    service: 'https://bsky.social',
    identifier: 'alice.bsky.social',
    password: 'wrong-password',
  })
} catch (err) {
  if (err instanceof LexAuthFactorError) {
    console.error('2FA required')
  } else if (err instanceof XrpcResponseError) {
    switch (err.error) {
      case 'AuthenticationRequired':
        console.error('Invalid credentials')
        break
      case 'AccountTakedown':
        console.error('Account has been suspended')
        break
      default:
        console.error('Login failed:', err.message)
    }
  } else {
    throw err
  }
}
```

常见错误代码 :

| 错误代码 | 说明 |
| --- | --- |
| `AuthenticationRequired` | 无效的用户名或密码 |
| `AuthFactorTokenRequired` | 需要2FA代码 |
| `AccountTakedown` | 账户已中止 |
| `ExpiredToken` | Token 已过期( 刷新) |
| `InvalidToken` | 托肯无效 |

## 使用客户端

这个 `PasswordSession` 执行 `Agent` 接口,可直接与 `Client`数字 :

```typescript
import { Client } from '@atproto/lex-client'
import { PasswordSession } from '@atproto/lex-password-session'
import * as app from './lexicons/app.js'

const session = await PasswordSession.login({
  service: 'https://bsky.social',
  identifier: 'alice.bsky.social',
  password: 'app-password',
})

const client = new Client(session)

// The client automatically uses the session for authentication
const profile = await client.call(app.bsky.actor.getProfile, {
  actor: client.assertDid,
})

// Tokens are automatically refreshed when expired
const timeline = await client.call(app.bsky.feed.getTimeline, {
  limit: 50,
})

// Create records
await client.create(app.bsky.feed.post, {
  text: 'Hello from lex-password-session!',
  createdAt: new Date().toISOString(),
})
```

会议处理:

-   添加中 `Authorization` 请求的页眉
-   检测过期代币(401份答复或 `ExpiredToken` 错误)
-   自动刷新令牌并重试失败的请求
-   根据 DD 文档向正确的 PDS 发送请求

## 许可证

麻省理工学院或Apachi2

## 常见问题

### @atproto/lex-password-session 是什么？

基于密码的AT Lexicons客户端认证

### 如何安装 @atproto/lex-password-session？

在项目目录运行 npm install @atproto/lex-password-session，或使用 pnpm add / yarn add / bun add。

### @atproto/lex-password-session 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @atproto/lex-password-session 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @atproto/lex-password-session 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=22。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @atproto/lex-password-session 可以商用吗？

@atproto/lex-password-session 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @atproto/lex-password-session 的下载量有多少？

根据 npm 官方下载统计，@atproto/lex-password-session 在 2026/10/07 – 2026/11/05 这 30 天内被下载 43,353 次，日均约 1,445 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @atproto/lex-password-session 还在维护吗？

最新版本 0\.3\.2 发布于 2026/11/06（1 天前）；至今共发布 47 个版本，其中过去 12 个月发布了 47 个；首次发布于 2026/01/09。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

