@atcute/oauth-browser-client

中文文档
5.1.0发布于 2026/09/230BSDES Module近 30 天下载 3067

aT 协议的最小 OAuth 浏览器客户端执行

中文使用文档
文档目录10 节
  1. 客户端元数据
  2. 使用量
  3. 配置
  4. 开始授权
  5. 最终授权
  6. 续会
  7. 签名退出
  8. 保密客户端模式
  9. vite 本地发展
  10. 说明

@ atute/oauth-浏览器-客户端

aT 协议的最小 OAuth 浏览器客户端 .

npm install @atcute/oauth-browser-client

用于 Web 扩展,使用 @atcute/oauth-node-client 换句话说.

客户端元数据

您的应用程序需要 OAuth 客户端元数据文档, 托管在公共 URL 。 这是授权 关于您的应用程序的服务器 :

{
    "client_id": "https://example.com/oauth-client-metadata.json",
    "client_name": "My App",
    "client_uri": "https://example.com",
    "redirect_uris": ["https://example.com/oauth/callback"],
    "scope": "atproto transition:generic",
    "grant_types": ["authorization_code", "refresh_token"],
    "response_types": ["code"],
    "token_endpoint_auth_method": "none",
    "application_type": "web",
    "dpop_bound_access_tokens": true
}

页:1 client_id 必须是此文档所在的 URL 。 见 OAuth 客户端元数据谱 用于所有可用的字段.

使用量

配置

调用 configureOAuth 使用此库中的任何其他功能之前 :

import { configureOAuth } from '@atcute/oauth-browser-client';

import {
    CompositeDidDocumentResolver,
    LocalActorResolver,
    PlcDidDocumentResolver,
    WebDidDocumentResolver,
    XrpcHandleResolver,
} from '@atcute/identity-resolver';

configureOAuth({
    metadata: {
        client_id: 'https://example.com/oauth-client-metadata.json',
        redirect_uri: 'https://example.com/oauth/callback',
    },
    identityResolver: new LocalActorResolver({
        handleResolver: new XrpcHandleResolver({
            serviceUrl: 'https://public.api.bsky.app',
        }),
        didDocumentResolver: new CompositeDidDocumentResolver({
            methods: {
                plc: new PlcDidDocumentResolver(),
                web: new WebDidDocumentResolver(),
            },
        }),
    }),
});

[注]
此示例使用 Bluesky 的 AppView 处理解析,因为web app缺乏直接的 DNS 访问权限. Bluesky可能按隐私政策记录处理决议 使用大小写.

开始授权

import { createAuthorizationUrl } from '@atcute/oauth-browser-client';

const authUrl = await createAuthorizationUrl({
    target: { type: 'account', identifier: 'mary.my.id' },
    scope: 'atproto transition:generic transition:chat.bsky',
});

await sleep(200); // let browser persist local storage
window.location.assign(authUrl);

最终授权

在您重新定向的 URL 上,提取参数并最后确定 :

import { Client } from '@atcute/client';
import { OAuthUserAgent, finalizeAuthorization } from '@atcute/oauth-browser-client';

// server redirects with params in hash, not search string
const params = new URLSearchParams(location.hash.slice(1));

// scrub params from URL to prevent replay
history.replaceState(null, '', location.pathname + location.search);

const { session } = await finalizeAuthorization(params);
const agent = new OAuthUserAgent(session);
const rpc = new Client({ handler: agent });

const { data } = await rpc.get('com.atproto.identity.resolveHandle', {
    params: { handle: 'mary.my.id' },
});

这段会话在内部持续,不要存放在别处. 田径公司签了字 您的用户界面, 因为没有刷新符号的会话可能会过期 .

续会

import { OAuthUserAgent, getSession } from '@atcute/oauth-browser-client';

const session = await getSession('did:plc:ia76kvnndjutgedggx2ibrem', {
    allowStale: true,
});
const agent = new OAuthUserAgent(session);

签名退出

import { OAuthUserAgent, deleteStoredSession, getSession } from '@atcute/oauth-browser-client';

const did = 'did:plc:ia76kvnndjutgedggx2ibrem';

try {
    const session = await getSession(did, { allowStale: true });
    const agent = new OAuthUserAgent(session);
    await agent.signOut();
} catch {
    deleteStoredSession(did); // fallback if signOut fails
}

保密客户端模式

默认情况下,此库将作为 公共客户端 会期较短。 页:1 设立为期较长的会议 客户端断言后端 启用 保密客户端模式。 。 。 .

添加 fetchClientAssertion 给你的配置。 后端 API 完全由您决定 - 这只是一个 示例:

configureOAuth({
    // ... existing config

    async fetchClientAssertion({ aud, createDpopProof }) {
        const htu = 'https://example.com/api/client-assertion';
        const dpop = await createDpopProof(htu);

        const response = await fetch(htu, {
            method: 'POST',
            headers: { dpop, 'content-type': 'application/json' },
            body: JSON.stringify({ aud }),
        });

        const data = await response.json();
        return {
            client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
            client_assertion: data.assertion,
        };
    },
});

您的后端验证 dpop 证明并签名客户端断言 jwt 包含 iss, (中文(简体) ), sub (两者) 你的客户身份, aud (授权服务器), exp, (中文(简体) ), jti (独特的非ce)和 cnf: { jkt } (单位:千美元) 允许从证据中生成密钥拇指印).

为保密模式更新客户端元数据 - 替换 token_endpoint_auth_method 与 private_key_jwt,添加 token_endpoint_auth_signing_alg: "ES256",并添加一个 jwks_uri 指点 你的公用钥匙.

vite 本地发展

AT 协议 OAuth 禁止 localhost - 使用时 127.0.0.1 相反:

// vite.config.ts
import { defineConfig } from 'vite';
import metadata from './public/oauth-client-metadata.json' with { type: 'json' };

const SERVER_HOST = '127.0.0.1';
const SERVER_PORT = 12520;

export default defineConfig({
    server: { host: SERVER_HOST, port: SERVER_PORT },
    plugins: [
        {
            name: 'oauth-envs',
            config(_conf, { command }) {
                if (command === 'build') {
                    process.env.VITE_OAUTH_CLIENT_ID = metadata.client_id;
                    process.env.VITE_OAUTH_REDIRECT_URI = metadata.redirect_uris[0];
                } else {
                    const redirectUri = `http://${SERVER_HOST}:${SERVER_PORT}${new URL(metadata.redirect_uris[0]).pathname}`;
                    process.env.VITE_OAUTH_CLIENT_ID =
                        `http://localhost?redirect_uri=${encodeURIComponent(redirectUri)}` +
                        `&scope=${encodeURIComponent(metadata.scope)}`;
                    process.env.VITE_OAUTH_REDIRECT_URI = redirectUri;
                }
                process.env.VITE_OAUTH_SCOPE = metadata.scope;
            },
        },
    ],
});

然后在代码中使用环境变量 :

configureOAuth({
    metadata: {
        client_id: import.meta.env.VITE_OAUTH_CLIENT_ID,
        redirect_uri: import.meta.env.VITE_OAUTH_REDIRECT_URI,
    },
    // ...
});

说明

  • 极少执行: 只有 ES256 DPop 密钥, 需要 PKCE 和 DPop 绑定 PAR
  • 无索引数据库:在Safari锁定模式下工作,但不能使用不可导出密钥作为 建议 由 DPoP 光谱
  • 有限测试:在个人项目中工作,但考虑 参考文献 执行 用于生产

版本与发布记录

@atcute/oauth-browser-client 共发布 43 个版本,首次发布于 2024/10/12;过去 12 个月发布了 10 个版本。

版本发布日期距今
5.1.0latest2026/09/231 个月前
5.0.22026/09/121 个月前
5.0.12026/09/101 个月前
5.0.02026/08/023 个月前
4.0.12026/06/304 个月前
4.0.02026/05/095 个月前

其他发布通道:alpha → 1.0.10-alpha.2,next → 2.0.0-next.0。

关于 @atcute/oauth-browser-client 的常见问题

@atcute/oauth-browser-client 是什么?

aT 协议的最小 OAuth 浏览器客户端执行

如何安装 @atcute/oauth-browser-client?

在项目目录运行 npm install @atcute/oauth-browser-client,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@atcute/lexicons(^2.0.0)、@atcute/identity-resolver(^2.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@atcute/oauth-browser-client 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/atcute__oauth-browser-client 是否存在。

@atcute/oauth-browser-client 支持 ESM 还是 CommonJS?

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

@atcute/oauth-browser-client 可以商用吗?

@atcute/oauth-browser-client 使用 0BSD 许可。几乎没有限制:可自由使用、修改和分发,连保留版权声明也不要求。以上为概括,不构成法律意见,请以许可原文为准。

@atcute/oauth-browser-client 的下载量有多少?

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

@atcute/oauth-browser-client 还在维护吗?

最新版本 5.1.0 发布于 2026/09/23(1 个月前);至今共发布 43 个版本,其中过去 12 个月发布了 10 个;首次发布于 2024/10/12。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。