@ atproto/ lex- password- session
基于密码的AT协议 Lexicons会话认证. 见 更改日志 用于版本历史.
npm install @atproto/lex-password-session
- 自动更新的会话管理
- 持续和监测会话状态的钩子
- PDS 从 DD 文档中发现端点
- 双要素认证支持
[大
此软件包目前处于 预览. API 和特性在稳定发布前会有所改变.
这是什么?
@atproto/lex-password-session 页:1 PasswordSession 类 Agent 界面从 @atproto/lex-client它与AT 协议服务处理基于密码的认证,包括:
- 创建带有用户名/密码证书的会话
- 访问令牌过期时自动刷新令牌
- 通过生命周期钩的会话持久性
- 使用服务器侧会话清理的优雅登录
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,
})
快速启动
1. 安装软件包
npm install @atproto/lex-password-session @atproto/lex-client
2. 登录和提出请求
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 类管理基于密码的认证会话.
登录
创建一个带有用户名和密码的新会话 :
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 被抛出.
双向认证
[叹息]
二要素认证仅适用于使用 主账户证书,这是 强烈反对密码认证 应用程序密码 仅仅因为它们是为程序访问(机器人,脚本,CLI工具)而设计的. 对于用户化应用程序,请通过 OAuth 使用 @atproto/oauth-客户端 提供更好的安全和用户控制.
如果账户启用了 2FA , 登录将丢入 LexAuthFactorError数字 :
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
}
}
复会
恢复先前保存的会话 :
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(),以确保会话是有效的,符号是时空的.
注销
结束会话并通知服务器 :
await session.logout()
登录后 :
- 这个
onDeleted钩子叫做 - 会议被标记为被销毁(第2段)
session.destroyed === true(中文(简体) ) - 将提出进一步的请求
'Logged out'
静态删除
删除会话而不创建会话实例:
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)
在不需要提出额外请求的情况下,这对清理情景有用.
创建账户
创建新账户并获得认证的会话 :
import { PasswordSession } from '@atproto/lex-password-session'
const session = await PasswordSession.createAccount(
{
handle: 'alice.bsky.social',
email: '[email protected]',
password: 'secure-password',
},
{
service: 'https://bsky.social',
onUpdated: (data) => saveToStorage(data),
onDeleted: (data) => removeFromStorage(data.did),
},
)
console.log('Account created:', session.did)
会话钩
Hooks为会话生命周期活动提供回调. 所有钩子收到会话实例为 this 上下文.
已更新
当会话成功创建或刷新时调用 :
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正在运行。 保持这个回调速度以避免延误.
更新失败
因瞬态错误( 网络问题, 服务器无法使用) , 令牌刷新失败时调用 :
{
onUpdateFailure(data, error) {
console.warn('Token refresh failed:', error.message)
// Session may still be valid - consider retry logic
}
}
已删除
当会话终止时调用( 日志或服务器侧无效) :
{
onDeleted(data) {
console.log('Session ended for:', data.did)
clearPersistedSession(data.did)
redirectToLogin()
}
}
已删除失败
因瞬间出错无法登录时调用 :
{
onDeleteFailure(data, error) {
console.error('Logout failed:', error.message)
// Consider queuing for retry to avoid orphaned sessions
queueLogoutRetry(data)
}
}
[尖叫声]
忽略删除失败可以让会话在服务器上活动. 执行安全敏感应用程序的重试逻辑.
会话数据
这个 SessionData 类型包含认证和恢复会话所需的全部数据 :
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 类使用基于例外的错误处理 :
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数字 :
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