浏览 SDKs · WASM
平台
SDKsWASM

认证与管理登录会话

使用 WASM SDK 登录、查询登录状态、处理连接事件并退出当前账号。

复制

WASM SDK 使用 login() 建立当前用户的登录会话。开始认证前,请先按照开始之前完成准备工作:OpenIMServer、用户登录信息、浏览器可访问的服务地址,以及 SDK 运行资源。

完整登录流程按以下顺序执行:

  1. 发布 WASM 资源并通过 getSDK() 创建 SDK 实例。
  2. 注册连接、Token 和账号下线事件,确保登录阶段的状态不会丢失。
  3. 从业务后端获取“开始之前”约定的 userID、Token、apiAddr 和 wsAddr。
  4. 调用 login(),等待 Promise 成功,并继续等待 OnConnectSuccess 确认连接可用。
  5. 连接成功后再查询用户、好友、会话、群组和消息数据。
  6. 用户主动退出或切换账号时调用 logout(),然后清理当前账号的应用状态和事件监听。

使用应用配置初始化 SDK

先发布浏览器 SDK 所需的 WASM 资源,再创建 SDK 实例。coreWasmPath 和 sqlWasmPath 必须指向浏览器可访问的资源路径。

import { getSDK, SdkEvent } from '@openim/wasm-client-sdk';

const openimsdk = getSDK({
  coreWasmPath: '/openIM.wasm',
  sqlWasmPath: '/sql-wasm.wasm',
});

参数说明

getSDK() 的配置字段如下:

参数类型是否必填说明
coreWasmPathstring否openIM.wasm 的浏览器可访问地址,未传时默认使用 /openIM.wasm。
sqlWasmPathstring否sql-wasm.wasm 的浏览器可访问地址;项目改变静态资源目录或使用 CDN 时应显式传入。
debugboolean否控制 JavaScript 包装层和本地数据库桥接的调试输出,默认开启。

理解浏览器包

@openim/wasm-client-sdk 是浏览器 WASM 包。getSDK() 在同一个页面运行环境中复用 SDK 实例,业务代码不应为不同组件重复创建实例。不要在服务端渲染阶段、Node.js API 路由或 Electron 主进程中初始化该实例。

OpenIMSDK 的应用配置分成两部分:WASM 资源路径在 getSDK() 时传入;OpenIMServer 地址和用户认证信息在 login() 时传入。

获取当前用户的登录信息

调用业务后端提供的登录信息接口,取得当前用户的 userID、Token 和 OpenIMServer 地址。接口的职责和返回结构见开始之前。

const { userID, token, apiAddr, wsAddr } = await loadOpenIMSDKSession();

userID 只是当前 OpenIMSDK 用户的标识,不是认证凭据;它必须与 Token 对应。浏览器只使用后端返回的登录信息,不负责创建用户或签发 Token。

在登录前注册连接事件

连接事件应在 login() 前注册。这样便可捕获登录阶段因网络、地址、Token 或服务端问题产生的错误,并更新连接状态。

const handleConnecting = () => {
  setConnectionState('connecting');
};

const handleConnectSuccess = () => {
  setConnectionState('connected');
};

const handleConnectFailed = ({ errCode, errMsg }) => {
  setConnectionState('failed');
  handleOpenIMError(errCode, errMsg);
};

openimsdk.on(SdkEvent.OnConnecting, handleConnecting);
openimsdk.on(SdkEvent.OnConnectSuccess, handleConnectSuccess);
openimsdk.on(SdkEvent.OnConnectFailed, handleConnectFailed);

登录当前用户

调用 login() 时传入 LoginParams。下面示例使用 Platform.Web,避免在业务代码中直接填写平台数字:

import { LogLevel, Platform } from '@openim/wasm-client-sdk';

try {
  await openimsdk.login({
    userID,
    token,
    platformID: Platform.Web,
    apiAddr,
    wsAddr,
    logLevel: LogLevel.Warn,
    isLogStandardOutput: false,
  });
} catch ({ errCode, errMsg }) {
  handleOpenIMError(errCode, errMsg);
  throw new Error(`OpenIMClientSDK login failed: ${errCode} ${errMsg}`);
}

参数说明

参数类型是否必填说明
userIDstring是当前 OpenIMSDK 用户 ID,必须与 Token 对应。它不是昵称、手机号或业务侧临时会话 ID。
tokenstring是业务后端返回的当前用户 OpenIMSDK Token,必须与 userID 对应。
platformIDnumber是当前客户端平台。浏览器使用 Platform.Web;桌面或移动端应按实际运行平台和服务端多端登录策略选择对应枚举。
apiAddrstring是OpenIMServer 的 HTTP API 地址,必须能从当前浏览器访问;HTTPS 页面应使用 HTTPS 地址。
wsAddrstring是OpenIMServer 的 WebSocket 地址,必须能从当前浏览器建立连接;HTTPS 页面通常使用 WSS 地址。
logLevelLogLevel否SDK 日志级别,枚举值见日志。
isLogStandardOutputboolean否是否把 SDK 核心日志输出到浏览器控制台。关闭该字段不等于关闭 getSDK({ debug }) 控制的 JavaScript 包装层日志。
isExternalExtensionsboolean否是否启用消息外部扩展能力;仅在服务端和业务已启用并实现对应扩展协议时设置为 true。
tryParseboolean否是否尝试把 SDK 返回的 JSON 字符串解析为对象,默认值为 true。关闭后,业务层需要自行解析响应数据。

login() 的 Promise 成功表示登录请求已经完成;OnConnectSuccess 表示 SDK 连接已经可用。两者是不同阶段,不能只因 Promise 成功就立即调用依赖连接的消息、会话、群组或用户 API。

重复点击登录时,应复用正在进行的登录请求及其 Promise,避免并发调用 login()。

处理 API 调用结果

WASM SDK 的异步 API 返回 Promise。调用成功时,从响应的 data 取得业务结果;调用失败时,Promise 会抛出包含 errCode 和 errMsg 的错误。各 API 页的“返回结果”只描述 data 的业务结构,不重复展开公共响应外层。

try {
  const { data } = await openimsdk.getSelfUserInfo();
  useCurrentUser(data);
} catch ({ errCode, errMsg }) {
  handleOpenIMError(errCode, errMsg);
}

查询 API 的 data 是调用时返回的业务数据。状态变更 API 没有可用于刷新界面的业务数据时,先等待 Promise,再根据页面说明处理相关事件或重新查询;不要把 Promise 成功、事件到达和最终界面状态视为同一个阶段。

复杂对象只在一个主要查询页完整说明字段,其他 API 页说明本次操作会使用的字段并链接到该结构,避免同一类型在多个页面出现不一致的字段表。

查询当前登录状态

getLoginStatus() 和 getLoginUserID() 都不接收业务参数:

import { LoginStatus } from '@openim/wasm-client-sdk';

const { data: loginStatus } = await openimsdk.getLoginStatus();

if (loginStatus === LoginStatus.LoggedIn) {
  const { data: currentUserID } = await openimsdk.getLoginUserID();
  restoreSessionFor(currentUserID);
}

LoginStatus 有三种状态:

状态说明
LoginStatus.LoggedOut当前 SDK 实例未登录。
LoginStatus.LoggingIn登录流程正在进行,不要再次发起并行登录。
LoginStatus.LoggedInSDK 已登录;仍应结合连接事件判断当前网络连接是否可用。

getLoginUserID() 返回 SDK 当前登录的用户 ID,适合校验应用账号与 SDK 账号是否一致;它不能替代业务侧身份认证。这两个查询的 Promise 成功后,可以直接使用各自的 data 恢复当前登录状态。查询本身不会触发连接事件。

切换账号时不要直接用新参数覆盖当前登录。先调用 logout() 完成旧账号退出并清理旧账号状态,再使用新账号参数调用 login()。

使用访问 Token

OpenIMSDK Token 由业务后端签发并返回给浏览器。前端把 Token 传给 login(),并在 Token 过期、无效或用户切换账号时重新进入认证流程。

const handleUserTokenExpired = async () => {
  await refreshSessionAndRelogin();
};

const handleUserTokenInvalid = ({ data: reason }) => {
  handleInvalidOpenIMToken(reason);
};

openimsdk.on(SdkEvent.OnUserTokenExpired, handleUserTokenExpired);
openimsdk.on(SdkEvent.OnUserTokenInvalid, handleUserTokenInvalid);

OnUserTokenInvalid 的 data 是 SDK 返回的原因字符串。刷新 Token 时,从业务后端请求新的 userID、Token 和服务地址,再根据应用的认证流程重新调用 login()。

会话 Token 差异

OpenIM WASM SDK 的浏览器登录流程不区分「访问 Token」和「会话 Token」这两类客户端凭据。对前端来说,login() 接收的是 OpenIMSDK Token。该 Token 的签发、有效期、刷新和撤销策略,由你的后端与 OpenIMServer 配置决定。

如果产品需要短期会话、一次性登录或多端策略,请在后端实现,并通过 Token 生命周期事件通知前端重新认证。

设置连接生命周期处理

除连接和 Token 事件外,还应处理账号被强制下线。该事件通常表示:同一账号在其他客户端登录、服务端策略要求当前端下线,或当前 Token 已不再适合继续使用。

const handleKickedOffline = () => {
  clearCurrentSession();
  handleForcedSignOut();
};

openimsdk.on(SdkEvent.OnKickedOffline, handleKickedOffline);

收到 OnKickedOffline 时,WASM SDK 已经自动退出当前登录会话,不要再调用 logout()。事件处理器清理应用自身保存的当前用户、会话列表、消息视图和页面状态,再进入应用的未登录流程。

断开与 OpenIMServer 的连接

用户主动退出登录或切换账号时,调用 logout(),再清理当前用户的会话列表、消息缓存、未读数和业务状态。被 OnKickedOffline 强制下线不属于主动退出,不要执行这里的 logout() 流程。

await openimsdk.logout();

clearCurrentSession();

logout() 的 Promise 成功表示当前 SDK 登录会话已经退出,随后再清理应用状态。不要只等待某个连接事件来判断主动退出完成。

logout() 不接收业务参数。切换账号时,先等待旧账号的 logout() Promise 成功,再移除旧事件监听、清空旧账号状态,然后调用新账号的 login()。不要让两个账号的登录和退出流程并发执行。

仅断开 WebSocket

OpenIM WASM SDK 不提供「仅断开 WebSocket、但保留登录会话」的独立方法。需要主动结束当前用户的会话时,使用 logout()。网络恢复和页面前后台切换由 SDK 包装层统一适配,应用仍应通过连接事件更新界面状态。

清理登录相关事件监听

本页集中提供连接、Token 和账号下线事件的完整监听示例。退出登录、切换账号或销毁 SDK 作用域时,使用注册时的同一组函数引用清理监听:

function removeSessionListeners() {
  openimsdk.off(SdkEvent.OnConnecting, handleConnecting);
  openimsdk.off(SdkEvent.OnConnectSuccess, handleConnectSuccess);
  openimsdk.off(SdkEvent.OnConnectFailed, handleConnectFailed);
  openimsdk.off(SdkEvent.OnUserTokenExpired, handleUserTokenExpired);
  openimsdk.off(SdkEvent.OnUserTokenInvalid, handleUserTokenInvalid);
  openimsdk.off(SdkEvent.OnKickedOffline, handleKickedOffline);
}

连接事件不对应某一条用户、会话或消息记录,应按当前 SDK 实例和登录用户隔离状态;切换账号前先移除旧实例监听。重新登录后,各功能通过对应事件同步数据变化;页面首次进入时再查询并显示所需数据。

下一步