
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
@brain-toolkit/brain-user
Advanced tools
Brain User Service - 完整的用户认证和管理库,适用于 Brain 平台
查看在线示例 - 基于 Vite + React 的完整示例项目
pnpm add @brain-toolkit/brain-user
import { BrainUserService } from '@brain-toolkit/brain-user';
const service = new BrainUserService({
env: 'production'
});
// 使用 Google 登录
const credentials = await service.loginWithGoogle({
authorization_code: 'google-oauth-code'
});
// 获取用户信息
const user = await service.getUserInfo();
console.log(user.email, user.name);
const service = new BrainUserService({
env: 'production' // 'development' | 'production' | string
});
| 属性 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
serviceName | string | 否 | 'brainUserService' | 服务标识符,用于日志和调试 |
executor | ExecutorInterface | 否 | - | 自定义异步操作执行器 |
logger | LoggerInterface | 否 | - | 自定义日志记录器 |
gateway | BrainUserGateway | 否 | 自动创建 | API 通信的网关实例 |
store | BrainUserStore | CreateBrainStoreOptions | 否 | 自动创建 | 用户数据和凭证的状态存储 |
| 属性 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
env | 'development' | 'production' | string | 否 | 'development' | 环境标识,用于确定 API 域名 |
domains | Record<string, string> | 否 | 见下方 | 自定义环境域名映射 |
baseURL | string | 否 | 从 env 自动获取 | 直接覆盖 API 基础 URL |
endpoints | Record<string, EndpointsType> | 否 | GATEWAY_BRAIN_USER_ENDPOINTS | 自定义 API 端点配置(格式:'METHOD /path') |
headers | Record<string, string> | 否 | - | 所有请求的默认请求头 |
responseType | 'json' | 'text' | 'blob' | 否 | 'json' | 期望的响应类型 |
| 属性 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
authKey | string | 否 | 'Authorization' | 认证令牌的请求头键名 |
tokenPrefix | string | 否 | 'token' | 令牌值的前缀(如 'Bearer', 'token') |
requiredToken | boolean | 否 | true | 请求是否需要令牌 |
storageKey | string | 否 | 'brain_profile' | 存储用户资料的键名 |
| 属性 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
store.storage | 'localStorage' | 'sessionStorage' | SyncStorageInterface | 否 | 'localStorage' | 用户数据的存储机制 |
store.persistUserInfo | boolean | 否 | false | 是否持久化用户信息到存储 |
store.credentialStorageKey | string | 否 | 'brain_token' | 存储凭证的键名 |
store.featureTags | DynamicFeatureTags | 否 | 自动创建 | 功能标签处理器实例 |
store.userProfile | UserProfile | 否 | 自动创建 | 用户资料处理器实例 |
| 属性 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
requestAdapter | RequestAdapterInterface | 否 | RequestAdapterFetch | 自定义 HTTP 通信请求适配器 |
{
development: 'https://brus-dev.api.brain.ai/v1.0/invoke/brain-user-system/method',
production: 'https://brus.api.brain.ai/v1.0/invoke/brain-user-system/method'
}
用户认证和管理的主服务类。
loginWithGoogle(params: BrainUserGoogleRequest): Promise<BrainGoogleCredentials>使用 Google OAuth 授权码登录。
注意: 此方法不会自动获取用户信息。登录成功后需要手动调用 refreshUserInfo() 来获取用户详情。
const credentials = await service.loginWithGoogle({
authorization_code: 'google-oauth-code'
});
// 然后刷新用户信息
const userInfo = await service.refreshUserInfo(credentials);
service.getStore().success(userInfo, credentials);
参数:
params.authorization_code (可选): Google OAuth 授权码params.id_token (可选): Google ID 令牌params.metadata (可选): 额外的元数据(例如,brain web 的 mode)返回: Promise,解析为包含 token 和可选 required_fields 的 Google 凭证
login(params: BrainLoginRequest): Promise<BrainCredentials | null>使用邮箱和密码登录。
const credentials = await service.login({
email: 'user@example.com',
password: 'password123'
});
参数:
params.email: 用户邮箱地址params.password: 用户密码params.metadata (可选): 额外的元数据返回: Promise,解析为凭证或 null
register(params: BrainUserRegisterRequest): Promise<BrainUser>注册新用户账户。
const user = await service.register({
email: 'user@example.com',
password: 'securePassword123',
first_name: 'John',
last_name: 'Doe'
});
参数:
params.email: 用户邮箱地址params.password: 用户密码params.first_name: 用户名字params.last_name: 用户姓氏params.otp (可选): 验证码params.metadata (可选): 额外的元数据params.roles (可选): 用户角色数组返回: Promise,解析为包含凭证的用户数据
getUserInfo(params?: BrainGetUserInfoRequest): Promise<BrainUser | null>获取当前用户信息。
const user = await service.getUserInfo();
// 或使用显式令牌
const user = await service.getUserInfo({ token: 'auth-token' });
参数:
params.token (可选): 认证令牌(如果未提供,则使用存储的令牌)返回: Promise,解析为用户数据或 null
refreshUserInfo(params?: BrainGetUserInfoRequest): Promise<BrainUser | null>从服务器刷新用户信息。
const updatedUser = await service.refreshUserInfo();
参数:
params.token (可选): 认证令牌(如果未提供,则使用存储的令牌)返回: Promise,解析为更新的用户数据或 null
logout(params?: unknown): Promise<void>登出当前用户。
await service.logout();
返回: Promise,解析为 void
getStore(): BrainUserStore<Tags>获取用户 store 实例以访问状态。
const store = service.getStore();
const user = store.getUserMe();
const token = store.getCredential()?.token;
返回: BrainUserStore 实例
getCredential(): BrainCredentials | null获取当前用户凭证。
const credential = service.getCredential();
if (credential?.token) {
// 用户已认证
}
返回: 凭证对象或 null
用户数据和凭证的状态存储。
getUserMe(): BrainUser | null从 store 获取当前用户数据。
getCredential(): BrainCredentials | null从 store 获取当前凭证。
featureTags: DynamicFeatureTags用于权限检查的功能标签处理器。
// 检查用户是否有 Gen UI 权限
const hasGenUI = service.getStore().featureTags.hasGenUI();
// 使用访客标志检查
const hasGenUI = service.getStore().featureTags.hasGenUI(true);
userProfile: UserProfile用于访问资料数据的用户资料处理器。
// 获取电话号码
const phone = service.getStore().userProfile.getPhoneNumber();
// 获取邮箱
const email = service.getStore().userProfile.getDaEmail();
// 检查邮箱验证状态
const isVerified = service.getStore().userProfile.isEmailVerified();
// 检查权限
const hasPermission = service
.getStore()
.userProfile.hasPermission('restricted_resources');
const service = new BrainUserService({
env: 'production'
});
// 使用 Google 登录
const credentials = await service.loginWithGoogle({
authorization_code: 'google-oauth-code'
});
// 获取用户信息
const user = await service.getUserInfo();
console.log(user.email, user.name);
// 检查功能权限
const hasGenUI = service.getStore().featureTags.hasGenUI();
// 访问用户资料
const phoneNumber = service.getStore().userProfile.getPhoneNumber();
const service = new BrainUserService({
env: 'production',
store: {
storage: 'sessionStorage', // 标签页关闭时清除数据
persistUserInfo: true,
credentialStorageKey: 'my_custom_token_key'
}
});
import { CookieStorage } from '@qlover/corekit-bridge';
const service = new BrainUserService({
env: 'production',
store: {
storage: new CookieStorage({
expires: 30, // 30 天
path: '/',
domain: '.example.com', // 跨子域名工作
secure: true, // 仅 HTTPS
sameSite: 'Lax' // CSRF 保护
}),
persistUserInfo: true
}
});
import { RequestAdapterFetch } from '@qlover/fe-corekit';
// 创建带拦截器的自定义适配器
const customAdapter = new RequestAdapterFetch({
baseURL: 'https://custom-api.example.com',
timeout: 10000,
headers: {
'X-App-Version': '1.0.0',
'X-Custom-Header': 'value'
}
});
const service = new BrainUserService({
requestAdapter: customAdapter
});
import { CustomLogger, CustomExecutor } from './custom';
const service = new BrainUserService({
env: 'production',
serviceName: 'myUserService',
logger: new CustomLogger(), // 自定义日志
executor: new CustomExecutor(), // 自定义异步执行
store: {
storage: 'localStorage',
persistUserInfo: true
}
});
const service = new BrainUserService({
env: 'staging',
domains: {
development: 'https://dev-api.example.com',
staging: 'https://staging-api.example.com',
production: 'https://api.example.com'
}
});
// 覆盖特定端点
const service = new BrainUserService({
env: 'production',
endpoints: {
login: 'POST /api/v2/auth/token.json',
getUserInfo: 'GET /api/v2/users/profile.json'
}
});
import { useState, useEffect } from 'react';
import { useSliceStore } from '@qlover/slice-store-react';
import { BrainUserService } from '@brain-toolkit/brain-user';
import { GatewayExecutor } from '@qlover/corekit-bridge/gateway-auth';
function App() {
const [userService] = useState(() => {
return new BrainUserService({
env: 'production',
executor: new GatewayExecutor()
});
});
const userStore = userService.getStore();
const user = useSliceStore(userStore, (state) => state.result);
const loading = useSliceStore(userStore, (state) => state.loading);
const error = useSliceStore(userStore, (state) => state.error);
useEffect(() => {
if (userService.getCredential()) {
userService.refreshUserInfo();
}
}, [userService]);
return (
<div>
{user ? (
<div>欢迎,{user.name}!</div>
) : (
<div>请登录</div>
)}
</div>
);
}
import type { BrainUserPluginInterface } from '@brain-toolkit/brain-user';
const userServicePlugin: BrainUserPluginInterface = {
pluginName: 'myUserServicePlugin',
onRefreshUserInfoBefore(context) {
context.parameters.store.updateState({
loading: true
});
},
onRefreshUserInfoSuccess(context) {
context.parameters.store.updateState({
loading: false
});
}
};
const service = new BrainUserService({
env: 'production'
}).use(userServicePlugin);
// 1. 初始化服务
const service = new BrainUserService({ env: 'production' });
// 2. 使用 Google 登录
const credentials = await service.loginWithGoogle({
authorization_code: googleAuthCode
});
// 3. 获取用户信息
const userInfo = await service.refreshUserInfo(credentials);
service.getStore().success(userInfo, credentials);
// 4. 检查权限
if (service.getStore().featureTags.hasGenUI()) {
// 用户有 Gen UI 权限
}
// 5. 登出
await service.logout();
const service = new BrainUserService({ env: 'production' });
// 注册新用户
const user = await service.register({
email: 'user@example.com',
password: 'securePassword123',
first_name: 'John',
last_name: 'Doe'
});
// 注册后用户自动登录
console.log('已注册用户:', user.email);
const service = new BrainUserService({ env: 'production' });
// 从服务器刷新用户信息
const updatedUser = await service.refreshUserInfo();
// 访问更新的资料
const email = service.getStore().userProfile.getDaEmail();
const isVerified = service.getStore().userProfile.isEmailVerified();
const service = new BrainUserService({
env: 'production',
store: { persistUserInfo: true }
});
// 从 store 获取用户(如果已持久化,页面重新加载后仍可用)
const user = service.getStore().getUserMe();
if (user) {
console.log('用户已登录:', user.email);
} else {
console.log('用户未登录');
}
const service = new BrainUserService({ env: 'production' });
const store = service.getStore();
// 检查功能权限
if (store.featureTags.hasGenUI()) {
// 显示 Gen UI 功能
}
if (store.featureTags.hasNoMeetingTab()) {
// 显示会议标签页
}
// 使用访客标志检查
const isGuest = service.getStore().getUserMe()?.is_guest ?? false;
if (store.featureTags.hasGenUI(isGuest)) {
// 为访客用户显示 Gen UI
}
const service = new BrainUserService({ env: 'production' });
const profile = service.getStore().userProfile;
// 获取资料数据
const phoneNumber = profile.getPhoneNumber();
const email = profile.getDaEmail();
const profileImage = profile.getProfileImgUrl();
// 检查验证状态
const isEmailVerified = profile.isEmailVerified();
// 检查权限
const hasPermission = profile.hasPermission('restricted_resources');
const permissionValue = profile.getPermissionValue('restricted_resources');
您可以定义自定义功能标签并保持类型安全:
type CustomTags = readonly [
'disable_custom_feature',
'disable_another_feature'
];
const service = new BrainUserService<CustomTags>({
env: 'production'
});
// 类型安全的功能检查
const hasCustomFeature = service.getStore().featureTags.hasCustomFeature();
const hasAnotherFeature = service.getStore().featureTags.hasAnotherFeature();
import { CookieStorage } from '@qlover/corekit-bridge';
import { RequestAdapterFetch } from '@qlover/fe-corekit';
const service = new BrainUserService({
// 服务配置
serviceName: 'brainUserService',
// API 配置
env: 'production',
headers: {
'X-App-Version': '1.0.0'
},
// 认证配置
authKey: 'Authorization',
tokenPrefix: 'Bearer',
requiredToken: true,
storageKey: 'user_profile',
// 存储配置
store: {
storage: new CookieStorage({
expires: 7,
path: '/',
domain: '.myapp.com',
secure: true
}),
persistUserInfo: true,
credentialStorageKey: 'auth_token'
},
// 自定义适配器
requestAdapter: new RequestAdapterFetch({
timeout: 15000
})
});
ISC
FAQs
Brain User Service - 完整的用户认证和管理库,适用于 Brain 平台
We found that @brain-toolkit/brain-user demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.