@amaster.ai/auth-client

中文文档
1.1.72发布于 2026/11/05MITTypeScriptESM + CJS近 30 天下载 1938

Amaster 平台的认证 SDK

中文使用文档
文档目录22 节
  1. 特征
  2. 安装
  3. 快速启动
  4. 配置
  5. 零配置( 建议)
  6. 可选配置
  7. 认证
  8. 登记册
  9. 登录
  10. OAuth 登录
  11. 迷你程序登录
  12. 注销
  13. 用户管理
  14. 获取当前用户
  15. 更新配置
  16. 更改密码
  17. 权限检查
  18. 匿名访问支持
  19. 本地权限检查( 快速)
  20. 组织职位
  21. 微信手机号授权直接登录
  22. 嵌入式浏览器会话

@amaster.ai/auth-客户端

Amaster 平台的认证 SDK - 与 OAuth 完成客户端认证解决方案,会话管理和权限检查.

特征

  • 🔐 多重认证方法: 用户名/电子邮件/电话+密码,验证码,OAuth
  • 🔄 自动刷新: JWT 证书在到期前自动更新
  • 📦 托肯存储: 支持安全部门改革的本地Storage或会话Storage
  • 🎯 权限系统: 基于角色和许可的访问控制
  • 👤 匿名访问: 自动支持具有可配置权限的匿名用户
  • 🔗 OAuth 整合: Google, GitHub, WeChat OAuth, WeChat Mini 程序, 定制 OAuth 供应商
  • 📡 事件系统: 倾听登录、登录和象征性事件
  • 💾 会话管理: 查看并撤销活动会话
  • 🔒 类型安全: 完整类型脚本支持

安装

pnpm add @amaster.ai/auth-client
# or
npm install @amaster.ai/auth-client

快速启动

import { createAuthClient } from "@amaster.ai/auth-client";

// Initialize the client (with optional callbacks)
const authClient = createAuthClient({
  onTokenExpired: () => {
    window.location.href = "/login";
  },
  onUnauthorized: () => {
    window.location.href = "/login";
  },
});

// Register a new user
await authClient.register({
  email: "[email protected]",
  password: "Password@123",
  displayName: "John Doe",
});

// Login
const result = await authClient.login({
  loginType: "email",
  email: "[email protected]",
  password: "Password@123",
});

if (result.data) {
  console.log("Logged in:", result.data.user);
}

// Get current user
const user = await authClient.getMe();

// Check permissions
if (authClient.hasPermission("user", "read")) {
  // Show user list
}

配置

SDK从盒子里出来 零配置数字 :

const authClient = createAuthClient();

// Storage auto-detects environment:
// - Browser → localStorage
// - WeChat Mini Program → wx.setStorageSync
// - SSR/Node.js → no-op (no persistence)

可选配置

interface AuthClientOptions {
  baseURL?: string; // API base URL, defaults to window.location.origin
  headers?: Record<string, string>; // Custom headers for all requests
  onTokenExpired?: () => void; // Token expiration callback
  onUnauthorized?: () => void; // Unauthorized (401) callback
  autoHandleOAuthCallback?: boolean; // Auto-handle OAuth callback hash on init, default true
  autoRedirectAfterLogin?: boolean; // Auto-consume ?redirect=... after any successful login, default true
}

示例

const authClient = createAuthClient({
  onTokenExpired: () => (window.location.href = "/login"),
  onUnauthorized: () => alert("Session expired"),
});

已建地物( Zero Config) :

  • * 自动环境检测(浏览器、微信程序、安全部门改革)
  • * 自动令牌刷新(过期前5分钟)
  • 自动权限同步
  • QQ 自动匿名支持
  • 智能存储(本地存储器, wx. storage, no-op for SSR)

认证

登记册

await authClient.register({
  email: "[email protected]",
  password: "Password@123",
  displayName: "John Doe",
});

与Captcha: (英语)

// 1. Get captcha
const captchaData = await authClient.getCaptcha();
document.getElementById("captcha-img").src = captchaData.data.captchaImage;

// 2. Register with captcha
const userInputCode = "AB12";
await authClient.register({
  email: "[email protected]",
  password: "Password@123",
  captcha: `${captchaData.data.captchaId}:${userInputCode}`,
});

登录

密码登录 :

await authClient.login({
  loginType: "email",
  email: "[email protected]",
  password: "Password@123",
});

校验码登录 :

// 1. Send code
await authClient.sendCode({
  type: "email",
  email: "[email protected]",
});

// 2. Login with code
await authClient.loginWithCode({
  loginType: "email",
  email: "[email protected]",
  code: "123456",
});

OAuth 登录

使用人工回调处理的全页重定向 :

const authClient = createAuthClient({
  autoHandleOAuthCallback: false,
});

// Login page
sessionStorage.setItem("oauth_redirect", "/dashboard");
authClient.loginWithOAuth("google");

// Callback page (/auth/callback)
const result = await authClient.handleOAuthCallback();
if (result.error) {
  console.error(result.error.message);
  return;
}
const redirectUrl = sessionStorage.getItem("oauth_redirect") || "/";
window.location.href = redirectUrl;

OAuth调用默认会自动处理. 不要同时打电话 handleOAuthCallback() 除非客户端是用 autoHandleOAuthCallback: false. 重复的电话是实例性的,但 选择一种模式可以使召回所有者明确无误.

如果回调页面 URL 已经携带 ?redirect=... 例如 /login?redirect=%2Fapi%2Foauth%2Fauthorize...SDK会重新使用 成功 OAuth 调用后自动重定向目标 。 两者 #access_token=... 财务报告和审定财务报表 #accessToken=... 支持调用hash格式.

默认,相同 ?redirect=... 处理也适用于密码登录, 校验码登录,注册自动登录,以及小型程序登录. 设定 autoRedirectAfterLogin: false 以禁用此行为并完全控制 应用层中的导航.

当 SDK 实际消耗方向目标时, 成功登录结果将 包含 result.data.redirectHandled === true 财务报告和审定财务报表 result.data.redirectTarget。 。 。 . 仍在运行自己的登录后导航的应用程序应当短路 在国旗上 避免双向.

WeCom 客户端 H5 登录 :

authClient.loginWithOAuth("wecom", "/dashboard");

这开始企业会员网页授权 在WeCom客户端, 不在普通浏览器中登录 QR 。 配置应用程序 collaboration.wecom 全权证书 enterprise-collaboration 添加 开始, 启用 wecom 内 auth.loginMethods,并初始化 返回页面。 默认的回调处理器会消耗符号散列并加载 当前用户。 一般 OAuth 重定向目标作为 redirect_uri 并且必须 成为应用程序本地路径或URL,其来源与运行时回调相同.

从一个公共登录页面开始 WeCom 登录. SDK记录了页面的路径和 查询为 error_redirect_uri,不包括 Stale OAuth 错误参数。 运行时间 返回已取消/ 登录失败 oauth_error 财务报告和审定财务报表 error_description· ; 缺少或过期状态又回到 /login提供公共路线(或 ),使错误成为隐藏的文本,并提议重试。 自动回调 处理不会产生错误 UI 。 对于授权的SSO,请在引用中呼叫 WeCom 认证应用并保存登录页面的路径名和查询为 成功返回目标,以便恢复其授权的继续.

应用范围 Feishu 登录 :

// The SDK uses requestAccess in the Feishu client and regular OAuth elsewhere.
// Pass a local path to restore the page that initiated login.
const result = await authClient.loginWithFeishu("/dashboard");

// Browser OAuth returns null because navigation has started. The callback page
// exchanges the short-lived, one-time login_ticket automatically.
if (result?.error) {
  console.error(result.error.message);
}

// /auth/callback, when autoHandleOAuthCallback is false
const callbackResult = await authClient.handleOAuthCallback();

Feishu App ID和 App 秘密属于当前应用环境, 不对平台进程。 SDK只接收公开的AppID. 应用程序 秘密停留在运行时,浏览器的回调带60秒的一次性 票而不是应用程序访问符。 飞须,SDK在等 window.h5sdk.ready() 在请求代码之前。 如果客户端不支持 requestAccess,SDK掉回 requestAuthCode。 。 。 .

已经获得飞虎代码的应用程序可以调用 loginWithFeishuCode(code, returnUrl)。回调也可以明确调用 exchangeOAuthLoginTicket(ticket),尽管 handleOAuthCallback() 一般情况 自动处理.

弹出窗口 :

// Main page
const popup = window.open("/api/auth/oauth/google", "oauth-login", "width=600,height=700");

window.addEventListener("message", (event) => {
  if (event.data.type === "oauth-success") {
    authClient.setAccessToken(event.data.accessToken);
    popup?.close();
  }
});

// Callback page
if (window.opener) {
  const result = await authClient.handleOAuthCallback();
  if (result.data?.accessToken) {
    window.opener.postMessage(
      { type: "oauth-success", accessToken: result.data.accessToken },
      origin
    );
  }
}

迷你程序登录

SDK曝光了针对WeChat和Douyin的统一的Mini Program API.

  • WeChat 运行时间: 自动检测 wx 并使用 WeChat 端点
  • Douyin 迷你程序:自动检测 tt 运行时间和使用 Douyin 端点
  • 非运行时间或混合环境:可以明确通过 platform

SDK 自动检测 Mini 程序存储运行时间并使用 WeChat wx.storage 或杜因语 tt.storage。 。 。 . 对于大多数应用代码,偏好高端方法:

  • miniLogin() - 自动打电话 Taro.login / 杜因语 tt.login / 微调 wx.login后端登录
  • miniGetPhone(...) - 接受原始代码或事件对象,提取电话代码,然后绑定电话号码
import { createAuthClient } from "@amaster.ai/auth-client";
import Taro from "@tarojs/taro";

// Zero configuration - auto-detects mini-program environment
const authClient = createAuthClient();

const result = await authClient.miniLogin();

if (result.data) {
  console.log("Logged in:", result.data.user);
  // Token automatically saved to mini-program storage
  Taro.switchTab({ url: "/pages/index/index" });
} else if (result.error) {
  Taro.showToast({
    title: result.error.message || "Login failed",
    icon: "none",
  });
}

登录 Douyin 迷你程序 :

const result = await authClient.miniLogin({
  platform: "douyin",
});

if (result.data) {
  console.log("Logged in:", result.data.user);
} else if (result.error) {
  Taro.showToast({
    title: result.error.message || "Login failed",
    icon: "none",
  });
}

获取用户电话号码( 可选) :

<!-- WXML -->
<button
  open-type="getPhoneNumber"
  bindgetphonenumber="onGetPhoneNumber"
>
  Get Phone Number
</button>
// JS
async onGetPhoneNumber(e) {
  const result = await authClient.miniGetPhone(e);

  if (result.data) {
    console.log("Phone number:", result.data.phone);
    console.log("Verified:", result.data.phoneVerified);

    // Update UI with phone number
    this.setData({
      phone: result.data.phone
    });
  } else if (result.error) {
    Taro.showToast({
      title: result.error.message || 'Failed to get phone number',
      icon: 'none'
    });
  } else {
    // User denied authorization
    console.log("User cancelled phone number authorization");
  }
}

获取 Douyin 迷你程序电话号码 :

async function onGetPhoneNumber(e) {
  const result = await authClient.miniGetPhone({
    ...e,
    platform: "douyin",
  });

  if (result.data) {
    console.log("Phone number:", result.data.phone);
  }
}

完整小型程序示例 :

// pages/login/login.js
import { createAuthClient } from "@amaster.ai/auth-client";
import Taro from "@tarojs/taro";

const authClient = createAuthClient();

Page({
  data: {
    userInfo: null,
    hasPhone: false,
  },

  // Auto-login on page load
  onLoad() {
    this.handleLogin();
  },

  // WeChat Mini Program login
  async handleLogin() {
    Taro.showLoading({ title: "Logging in..." });

    const result = await authClient.miniLogin();

    Taro.hideLoading();

    if (result.data) {
      this.setData({
        userInfo: result.data.user,
      });

      // Navigate to home
      Taro.switchTab({ url: "/pages/index/index" });
    } else {
      Taro.showToast({
        title: "Login failed",
        icon: "none",
      });
    }
  },

  // Get phone number with user authorization
  async onGetPhoneNumber(e) {
    const { code } = e.detail;

    if (!code) {
      Taro.showToast({
        title: "Authorization cancelled",
        icon: "none",
      });
      return;
    }

    Taro.showLoading({ title: "Getting phone..." });

    const result = await authClient.miniGetPhone(e);

    Taro.hideLoading();

    if (result.data) {
      this.setData({
        hasPhone: true,
      });

      Taro.showToast({
        title: "Phone number obtained",
        icon: "success",
      });
    } else {
      Taro.showToast({
        title: result.error?.message || "Failed to get phone",
        icon: "none",
      });
    }
  },
});

低等相容性 API( 已过期, 仅高级使用):

如果您的应用程序已经登录 code 电话 code,你还可以打电话:

  • loginWithMiniProgram(code | { code, platform })
  • getMiniProgramPhoneNumber(code | { code, platform })

注销

await authClient.logout();

用户管理

获取当前用户

const result = await authClient.getMe();
if (result.data) {
  console.log(result.data); // User object
}

更新配置

await authClient.updateMe({
  displayName: "New Name",
  avatarUrl: "https://example.com/avatar.jpg",
});

更改密码

await authClient.changePassword({
  oldPassword: "OldPassword@123",
  newPassword: "NewPassword@123",
});

权限检查

匿名访问支持

SDK 自动支持匿名用户 零配置数字 :

// Create client
const authClient = createAuthClient();

// Permission checks work for both authenticated and anonymous users
if (authClient.hasPermission("article", "read")) {
  showArticleList();
}

// Check if user is anonymous
if (authClient.isAnonymous()) {
  showLoginPrompt();
}

// After login, permissions automatically update
await authClient.login({ ... });

本地权限检查( 快速)

本地缓存权限用于快速UI检查 :

// Check role
if (authClient.hasRole("admin")) {
  showAdminPanel();
}

if (authClient.isAnonymous()) {
  showLoginPrompt();
}

// Check permission
if (authClient.hasPermission("user", "read")) {
  showUserList();
}

## OAuth Bindings

### Get Bindings

```typescript
const result = await authClient.getOAuthBindings();
if (result.data) {
  console.log(result.data); // Array of OAuthBinding
}
```

### Bind OAuth Account

```typescript
authClient.bindOAuth("google"); // Redirects to OAuth flow
```

### Unbind OAuth Account

```typescript
await authClient.unbindOAuth("google");
```

## Session Management

### Get Sessions

```typescript
const result = await authClient.getSessions();
if (result.data) {
  result.data.forEach((session) => {
    console.log(session.ip, session.userAgent, session.isCurrent);
  });
}
```

### Revoke Session

```typescript
await authClient.revokeSession("session-id");
```

### Revoke All Sessions

```typescript
const result = await authClient.revokeAllSessions();
if (result.data) {
  console.log(`Revoked ${result.data.revokedCount} sessions`);
}
```

## Event System

### Available Events

- `login` - User logged in, callback: `(user: User) => void`
- `logout` - User logged out, callback: `() => void`
- `tokenExpired` - Token expired, callback: `() => void`
- `tokenRefreshed` - Token refreshed, callback: `(token: string) => void`
- `unauthorized` - Unauthorized (401), callback: `() => void`

### Usage

```typescript
// Subscribe to events
authClient.on("unauthorized", () => {
  authClient.clearAuth();
  window.location.href = "/login";
});

authClient.on("login", (user) => {
  console.log("User logged in:", user.displayName);
});

authClient.on("tokenRefreshed", (token) => {
  console.log("Token refreshed");
});

// Unsubscribe
const handler = () => console.log("Logged out");
authClient.on("logout", handler);
authClient.off("logout", handler);
```

## Utility Methods

### Check Authentication Status

```typescript
if (authClient.isAuthenticated()) {
  // User is logged in
}
```

### Get Access Token

```typescript
const token = authClient.getAccessToken();
```

### Set Access Token

```typescript
authClient.setAccessToken("your-token-here");
```

### Clear Auth Data

```typescript
authClient.clearAuth(); // Clears token and user data
```

## Error Handling

```typescript
try {
  await authClient.login({ ... });
} catch (error) {
  // Network error or exception
  console.error("Login failed:", error);
}

// Or use result pattern
const result = await authClient.login({ ... });
if (result.error) {
  // API error response
  if (result.error.status === 401) {
    alert("Invalid email or password");
  } else if (result.error.status === 403) {
    alert("Account is disabled");
  } else {
    alert(`Login failed: ${result.error.message}`);
  }
}
```

## Best Practices

### Token Management

- Tokens are automatically managed by the SDK
- Access Token refreshes 5 minutes before expiration
- No manual token handling required

### Permission Checks

- Use permission checks for UI control (show/hide buttons, menus)
- Frontend checks are NOT security measures
- Backend must always verify permissions

### SSR Support

The SDK works in both browser and SSR environments:

```typescript
const authClient = createAuthClient();
```

## TypeScript

Full TypeScript support:

```typescript
import type {
  User,
  LoginResponse,
  Session,
  OAuthBinding,
} from "@amaster.ai/auth-client";
```

## License

MIT

## Contributing

Contributions are welcome! Please read our contributing guidelines before submitting PRs.

组织职位

const result = await client.auth.getPositions(); // unified application client
if (result.error) throw new Error(result.error.message);
// result.data: DepartmentPosition[] — { code, name, description? }

独立认证客户端曝光相同 authClient.getPositions() 方法。 它利用公众 /api/org/positions 带有当前访问符并需要的结束点 org.read。运行时间解决当前应用/环境和 authRef。配置的代码用于会员和BPM规则;名称用于显示。 空配置返回一个空阵列; 授权和服务失败仍然是错误 .

微信手机号授权直接登录

auth.miniPhoneLogin(e) 接收微信 getPhoneNumber 密码 { code, platform: 'wechat' }。无需预先调用 miniLogin()托肯 托肯 托肯 托肯。

async function onPhoneLogin(e) {
  if (!e.detail?.code) return;
  const result = await auth.miniPhoneLogin(e);
  if (result.error) {
    wx.showToast({ title: result.error.message, icon: 'none' });
    return;
  }
  // 登录状态已经保存,按应用现有规则导航。
}

后端使用微信验证的手机号匹配已有账号; 没有账号时遵循应用注册开关。停用账号、关闭注册时的新用户、重复手机号账号均拒绝登录。此方法不关联 OpenID, 12421 存档副本 miniLogin() 3⁄4 ̄ ̧漯B miniGetPhone() 保持不变。需要先部署支持 POST /api/auth/miniprogram/phone-login cha 运行时间。

嵌入式浏览器会话

使用 createAuthClient({ baseURL: applicationOrigin, withCredentials: true, storage: createMemoryStorage(), autoHandleOAuthCallback: false, autoRedirectAfterLogin: false })。 。 。 . restoreSession() 使用现有的应用程序刷新 cookie,加载应用程序用户并开始正常更新. 明确的存储适配器或调用 restoreSession() 选择更新连接、延期重新安排和待答复保护。 现有客户端既未保留存储,刷新请求/计时器行为和配置响应处理; cookie credits 仍可选入.

getOAuthLoginURL(provider, applicationRelativeReturnPath) 解析与 API 源码相对并让一个主机打开弹出. 在应用程序正常的 OAuth 调用后设置其 HttpOnresh cookie, 一个静态的应用程序起源的补全页面可以调用 completeOAuthPopup()它消耗 requestId 财务报告和审定财务报表 openerOrigin 从它的查询中清除它的查询/断层,并只发出 { type: "amaster:oauth-complete", requestId }。呼叫者必须验证信件的来源、准确的弹出和待处理的请求,然后通过正常的API恢复应用程序会话。 信件没有发送任何令牌或刷新证书 .

现有 loginWithOAuth() 保持其当前来源的导航和提供者行为,包括何时 baseURL 在另一个来源点。 在需要应用程序原产地导航时明确使用新的URL方法.

公众 AuthClient 财务报告和审定财务报表 AuthModule 类型保留其原有的方法集,因此现有的执行和模拟不需要浏览器会话方法. 默认工厂签名和 ReturnType<typeof createAuthClient> 保留 AuthClient明确 storage 或者说 withCredentials 选项选择 BrowserAuthClient 超载, 曝光 restoreSession() 财务报告和审定财务报表 getOAuthLoginURL() 没有石膏。 使用 BrowserAuthClientOptions 用于明确输入的浏览器配置和 BrowserAuthClient (a) 长期结果 AuthClient。 。 。 .

跨原产地饼干请求需要应用程序的现有网关,以允许准确的主机来源和证书. HTTPS和浏览器 cookie 政策仍然适用. SDK从未创建应用程序权限或代用服务/开发者证书.

版本与发布记录

@amaster.ai/auth-client 共发布 203 个版本,首次发布于 2026/02/02;过去 12 个月发布了 203 个版本。

版本发布日期距今
1.1.72latest2026/11/052 天前
1.1.712026/10/2514 天前
1.1.702026/10/081 个月前
1.1.692026/09/241 个月前
1.1.69-beta.0beta2026/09/231 个月前
1.1.682026/09/221 个月前

关于 @amaster.ai/auth-client 的常见问题

@amaster.ai/auth-client 是什么?

Amaster 平台的认证 SDK

如何安装 @amaster.ai/auth-client?

在项目目录运行 npm install @amaster.ai/auth-client,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:axios(^1.11.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@amaster.ai/auth-client 支持 TypeScript 吗?

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

@amaster.ai/auth-client 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@amaster.ai/auth-client 可以商用吗?

@amaster.ai/auth-client 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@amaster.ai/auth-client 的下载量有多少?

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

@amaster.ai/auth-client 还在维护吗?

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