Flutter

登录 IM

更新时间: 2024/08/13 15:37:24

完成 NIM SDK 的初始化之后,您需要先调用 SDK 的登录接口登录 IM。登录成功后,您才能正常调用消息和会话等其他 SDK 接口。

本文介绍账号集成与登录的技术原理、实现 IM 登录的流程、IM 登录状态转换流程,以及 相关常见问题

技术原理

IM 的登录与账号集成密切相关。上图展示了应用集成 NIM SDK 后,从账号集成到登录 IM 成功的主要流程:

  1. 用户在应用客户端注册用户账号时,由应用服务端向网易云信服务端发起 创建 IM 账号 的请求。
  2. IM 账号创建成功后,网易云信服务端会返回该 IM 账号(即 accid)和 token 等信息。此时,应用服务端需要负责保存 accidtoken 的映射关系。
  3. 应用客户端发起登录请求时,先走应用自有的登录验证逻辑,如账号和密码的验证。
  4. 验证成功后,应用服务端将与该用户对应的 accidtoken 等信息返回给应用客户端。此时,应用客户端需要负责保存 accidtoken 的映射关系。
  5. 当应用客户端需要调用网易云信的 IM 服务时,需要先进行 token 验证,以登录 IM 服务。
  6. token 验证成功后,应用客户端登录 IM 服务成功。之后用户便可调用 NIM SDK 的相关接口使用 IM 服务,如进行 IM 消息收发。
  • 终端用户使用网易云信 IM 服务时,应用本身的用户账号和网易云信的 IM 账号(accid彼此独立。网易云信的 IM 账号只用于网易云信 IM 服务的鉴权,IM 账号并不等同于应用的用户账号
  • 应用的用户账号和密码,与网易云信登录 IM 使用的 accidtoken 完全不一致。accidtoken 不由终端用户创建,而是由应用服务端分配,以保证安全性。

前提条件

API 调用时序

下图展示了与用户首次登录登出相关的 API 的调用时序,图中的 NIM 表示 NIM Flutter SDK。

uml diagram

步骤 1:准备 Token

登录 IM 需要通过 Token 进行鉴权。网易云信支持静态和动态两种 Token 类型,您可根据业务需求进行选择。

  • 静态 Token:默认为永久有效。如有需要,可通过网易云信服务端 API 主动刷新 Token

  • 动态 Token:具备时效性,可在生成时设置有效期。

获取静态 Token

  • 方式 1:在 网易云信控制台 获取静态 Token

    如果您只需要进行简单的 体验或者快速测试,那么可以在 网易云信控制台 创建测试用的 IM 账号,并获取与该 IM 账号相应的静态 token。获取的静态 token 可用于下文提及的静态 Token 登录

  • 方式 2:调用服务端 API 获取静态 Token

    如果您有正式的 生产环境,且您的业务 仅需保障基础的用户信息安全,那么可通过网易云信 IM 服务端 API 注册 IM 账号,并获取与之相对应的静态 token,具体参考 注册网易云信 IM 账号。获取的静态 token 可用于 静态 Token 登录 的鉴权。

获取动态 Token

如果您有正式的 生产环境,且您的业务 对用户信息安全有较高的要求,可使用动态 token。动态 token 可用于 动态 Token 登录 的鉴权。

  1. 注册网易云信 IM 账号,获取 IM 账号(accid)和静态 token

  2. 基于 App Key、App Secret 和 accid,通过 约定算法 在应用服务端生成 动态 token

    如果使用该方式,且您的应用需要调用网易云信的聊天室能力,那么要实现动态 token 登录,既要传入动态 token(通过下文提及的 AuthService#dynamicTokenProvider),也要传入静态 token

步骤 2:监听登录状态

通过登录状态事件流(authStatus)监听当前登录状态。

目前登录状态事件包含两类:

  • NIMAuthStatusEvent:通用登录状态事件,包含 NIMAuthStatus 登录状态枚举(具体枚举值见下表)。

  • NIMKickOutByOtherClientEvent:被踢事件,包含状态字段与额外属性。在使用时,需要根据具体类型进行解析。

    NIMAuthStatus 说明
    unknown 未定义
    unLogin 未登录/登录失败
    netBroken 网络连接已断开
    connecting 正在连接网易云信服务端
    logging 正在登录中
    loggedIn 已成功登录
    kickOut 被其他端的登录踢掉,此时应该跳转至手动登录界面。被踢后,无法自动登录
    kickOutByOtherClient 被同时在线的其他端主动踢掉(通过 kickOutOtherOnlineClient 方法),此时应该跳转至手动登录界面。被踢后,无法自动登录
    forbidden 被网易云信服务端禁止登录 网易云信 IM 账号被禁用。被禁止登录后,无法自动登录
    versionError SDK 版本错误。出现该登录异常后,无法自动登录
    pwdError 网易云信 IM 账号(account)或 token 错误。出现该登录异常后,无法自动登录
    • SDK 暂不支持主动查询当前账号是否处于在线状态,请监听登录状态变化并进行状态缓存。
    • 登录状态变化流程相关详情,请参考下文的 登录状态变化流程

    示例代码如下:

    Dart/// 开始监听事件
    final subscription = NimCore.instance.authService.authStatus.listen((event) {
    if (event is NIMKickOutByOtherClientEvent) {
        /// 监听到被踢事件
    } else if (event is NIMAuthStatusEvent) {
        /// 监听到其他事件
    }
    });
    
    /// 不再监听时,需要取消监听,否则造成内存泄漏
    /// subscription.cancel();
    

步骤 3:监听数据同步状态

登录成功后,SDK 会自动同步群信息、离线消息、漫游消息和系统通知等数据。数据同步过程会广播数据同步状态变更事件(NIMDataSyncStatusEvent),可通过以下接口监听该事件。

Dartclass AuthService {
    /// 登录状态变更事件
    Stream<NIMAuthStatusEvent> get authStatus;
}

数据同步状态事件包含一个类型为 NIMAuthStatus 的登录状态字段,标识当前同步状态:

NIMAuthStatus 说明
NIMAuthStatus.dataSyncStart 数据同步开始
NIMAuthStatus.dataSyncFinish 数据同步完成
  • Windows 和 macOS 暂不支持监听数据同步状态变化。
  • 数据同步完成时,整个登录过程才算真正完成。

示例代码如下:

Dart/// 开始监听事件
final subscription = NimCore.instance.authService.authStatus.listen((event) {
    if (event is NIMDataSyncStatusEvent) {
    /// 监听到数据同步事件
    if (event.status == NIMAuthStatus.dataSyncStart) {
        /// 数据同步开始
    } else if (event.status == NIMAuthStatus.dataSyncFinish) {
        /// 数据同步完成
    }
    }
});

/// 不再监听时,需要取消监听,否则造成内存泄漏
/// subscription.cancel();

步骤 4:登录 IM

登录方式概览

NIM SDK 登录方式分为两大类,即手动登录和自动登录。其中手动登录可进一步分为静态 token 登录、动态 token 登录和通过第三方回调登录。

您可按需实现 一种或多种 手动登录方式,并 在手动登录成功后,实现自动登录。

登录方式
子方式 鉴权方式 使用场景
手动登录 静态 Token 登录 静态 Token 鉴权 如下登录场景,用户需要手动登录 IM:
  • 在新设备上首次登录 IM
  • 被同时在线的其他设备踢下线后再次登录 IM
  • 切换 IM 账号后再次登录 IM
  • 注销登录后再次登录 IM
动态 Token 登录 动态 Token 鉴权
通过第三方回调登录 通过第三方回调鉴权
自动登录 继承手动登录的方式 继承手动登录的鉴权方式 应用被清理后,用户再次单击应用图标启动应用时,无需输入用户名和密码即可完成登录的场景。自动登录需在手动登录成功后使用

推荐 在手动登录成功后,将 accidtoken 保存到本地,方便下次应用启动进行初始化时,在 NIMSDKOptionsautoLoginInfo 中传入,实现自动登录。更多相关说明,参考 IM 登录最佳实践

方式 1:手动登录

静态 Token 登录

调用 login 方法手动登录 IM。调用时需将 authType 参数设置为 authTypeDefault

调用后,NIM SDK 会自动连接网易云信服务端,传递用户信息,返回登录结果。登录过程中可主动取消登录。如果因为网络或其他原因导致网易云信服务端长时间未响应,用户也没有主动取消登录,NIM SDK 将在 45 秒后自动重新连接网易云信服务端,并返回错误码,错误码详情参考下文的 手动登录错误码

是否必传 说明
account 用户的 IM 账号,即 accid
token 获取到的静态 token
authType 登录 IM 的鉴权方式。采用静态 token 登录时,使用 默认的 authTypeDefault 即可,即静态 token 鉴权
customClientType 自定义客户端类型,小于或等于 0 则视为没有自定义类型

示例代码如下:

DartNimCore.instance.authService
    .login(NIMLoginInfo(account: 'account', token: 'token',))
    .then(
      (result) {
        if (result.isSuccess) {
          /// 登录成功
        } else {
          /// 登录失败
        }
      },
    );

动态 Token 登录

动态 token 具备时效性,可有效提升 token 破解难度,降低密码泄露风险。

要实现动态 token 登录 IM,需完成如下两步操作:

  1. 通过 AuthService#dynamicTokenProvider方法获取上文中提及的基于 App Secret 生成的动态 Token

  2. 调用 login 方法手动登录 IM,调用时需将 authType 设置为 authTypeDynamic

    调用后,NIM SDK 会自动连接网易云信服务端,传递用户信息,返回登录结果。登录过程中可主动取消登录。如果因为网络或其他原因导致网易云信服务端长时间未响应,用户也没有主动取消登录,NIM SDK 将在 45 秒后自动重新连接网易云信服务端,并返回错误码,错误码详情参考下文的 手动登录错误码

    具体参数说明如下:

    是否必传 说明
    account 用户的 IM 账号,即 accid
    authType 该登录方式必传 采用动态 token 登录时必须传入 authTypeDynamic,表示通过动态 token 鉴权,动态 token基于 App Secret 计算生成
    token 视情况而定 获取到的静态 token。采用动态 token 登录时,如果您的应用不需要调用网易云信的聊天室能力,那么不需要传入静态 token。如果需要,那么必须传入静态 token
    customClientType 自定义客户端类型,小于或等于 0 则视为没有自定义类型

    示例代码如下:

    DartNimCore.instance.authService.dynamicTokenProvider = (account) async {
            //...生成动态 token
            return token;
        };
    
    loginResult = await NimCore.instance.authService.login(NIMLoginInfo(
            account: account,
            token: token,
            authType: NIMAuthType.authTypeDynamic,
        ));
    

通过第三方回调登录

如采用该登录方式,网易云信服务端不做 IM 登录鉴权,鉴权工作需由指定的第三方服务器(可以是应用服务器)进行。

实现该登录方式,需完成如下 3 步操作:

  1. 前往网易云信控制台,并进入 IM 即时通讯 > 功能配置 > 第三方回调 配置第三方回调的环境地址(即第三方服务器地址)和回调失败时放行(通过)与否。

    第三方回调配置文案优化后.png
  2. 调用 login 方法手动登录 IM,调用时需将 authType 设置为 authTypeThirdParty,且必须传入 loginExt

    调用后,NIM SDK 会自动连接网易云信服务端,传递用户信息,返回登录结果。登录过程中可主动取消登录。如果因为网络或其他原因导致网易云信服务端长时间未响应,用户也没有主动取消登录,NIM SDK 将在 45 秒后自动重新连接网易云信服务端,并返回错误码,错误码详情参考下文的 手动登录错误码

    具体参数说明如下:

    是否必传 说明
    account 用户的 IM 账号,即 accid
    authType 该登录方式必传 采用第三方回调登录时必须传入 authTypeThirdParty,表示通过第三方回调进行鉴权。
    loginExt 该登录方式必传 登录自定义扩展字段,长度上限为 1k 字符。采用该登录方式时,必须传入,用于第三方服务器鉴权。如未传入,将返回 LoginInfo is invalid 的报错信息。
    token 视情况而定 获取到的静态 token。采用动态 token 登录时,如果您的应用不需要调用网易云信的聊天室能力,那么不需要传入静态 token。如果需要,那么 必须传入 静态 token
    customClientType 自定义客户端类型,小于或等于 0 则视为没有自定义类型。
  3. 发起 登录相关回调 的请求,由第三方服务器进行鉴权并判定 IM 登录事件是否放行通过。

    若不通过,网易云信服务端将返回 302 错误码。

方式 2:自动登录

自动登录一般用于应用被清理后,用户再次单击应用图标启动应用时,无需输入用户名和密码即可完成登录的场景。此时应用可以在无网络、未登录成功的状态下直接访问用户本地 SDK 数据。自动登录与手动登录在客户端侧和服务端逻辑上的区别,参考文末的 常见问题

实现自动登录的方式为,在调用 initialize 方法初始化 SDK 时,将本地保存的 accounttoken 传入 NIMAndroidSDKOptionsNIMIOSSDKOptions 的自动登录信息(autoLoginInfo)。

示例代码如下:

DartNimCore.instance.initialize(
  NIMAndroidSDKOptions(
    appKey: 'appkey',
    autoLoginInfo: NIMLoginInfo(
      account: 'account',
      token: 'token',
    ),
  ),
).then(
  (result) {
    if (result.isSuccess) {
      /// 初始化成功
    } else {
      /// 初始化失败
    }
  },
);

相关信息

手动登录错误码

手动登录失败的错误码说明如下:

错误码 说明
302 App Key、accidtoken 三者不对应
408 与网易云信服务端的连接超时
415 网络断开或者连接网易云信服务端失败
416 调用手动登录接口过于频繁
1000 本地数据库未打开。请在手动登录成功后打开本地数据库

断网重连机制

SDK 提供了自动重连机制(自动重新建立与网易云信服务端的连接并重新登录),所有重连的登录状态变更都会触发 NIMAuthStatusEvent 事件回调。

SDK 在两种场景下会自动进行重连:

  • 手动/自动登录成功后,网络不佳导致连接断开的情况。
  • 网络不佳时,账号密码本身正常(未被 封禁,且账号密码均正确),启动应用时调用自动登录接口的情况。

满足上述中一个条件,当用户遇到普通网络问题如连接超时等,会自动进行重连登录,不需要上层开发者去做额外的重登逻辑

多端登录与互踢

当前 NIM SDK 支持配置四种不同的 IM 多端登录与互踢策略,具体参考 多端登录与互踢

登录状态转换流程

登录状态变化流程(不包含被踢下线和被 IM 服务端禁止登录等特殊状态)参考下图。图中,深蓝色元素代表登录状态,浅绿色元素代表自动登录或调用 login 方法的手动登录。

unLogin
unLogin
connecting
connecting
网络连接是否良好
网络连接是否良好
netBroken
netBroken
是否存在物理网络
是否存在物理网络
connecting
connecting
网络连接是否良好
网络连接是否良好
logging
logging
网络连接是否良好
网络连接是否良好
loggedIn
loggedIn
网络连接是否良好
网络连接是否良好
开始
开始
连接/重连
连接/重连
Text is not SVG - cannot display

常见问题

手动登录和自动登录的主要区别是什么?

手动登录和自动登录主要在于:

差异点
说明
NIM SDK 是否接管登录失败后的处理
  • 手动登录:NIM SDK 认为手动登录即是终端用户发起登录的流程,因此在登录失败后(如网络情况不佳、密码错误),NIM SDK 会触发相应回调,并停止重连操作,等待用户再次发起登录操作
  • 自动登录:自动登录失败后仍旧尝试重连,直到登录成功为止(密码错误等情况除外)
网易云信服务端是否验证当前登录设备的安全性
  • 手动登录:不验证
  • 自动登录:自动登录时,如果当前登录设备不是上一次登录设备,网易云信服务端会自动禁止其登录,以保证安全性。

如您选择自动登录,当您的应用在后台被唤起时,会计算为 1 次登录行为,计入日活统计作为计费依据。

断线后是否会自动重连?

一旦登录成功后(或者调用过自动登录),NIM SDK 将接管所有的重连情况:在网络正常的情况下不停重试重连直到正常登录为止,并不需要做额外的登录操作(聊天室同理)。

如何根据产品形态选择 IM 登录方式?

接入网易云信 IM 服务的产品大致分为两种形态:

  • IM 产品:通讯作为其核心模块。典型例子如微信、易信、网络直播相关应用。
  • 非 IM 产品:通讯只是其附带模块,典型例子如各种有私信模块的应用。

对于 IM 产品,由于通讯能力是核心能力,如果网易云信无法登录成功则整个应用将无法正常表现,所以推荐在执行业务逻辑前,首先完成应用服务端和网易云信服务端的登录。只有应用服务端和网易云信服务端都登录成功才认为整个登录完成。而对于非 IM 产品而言,通讯能力是可以在登录应用服务端成功后延迟加载,登录成功拿到服务端下发的网易云信 IM 账号和 token 后进行自动登录即可。

此文档是否对你有帮助?
有帮助
去反馈
  • 技术原理
  • 前提条件
  • API 调用时序
  • 步骤 1:准备 Token
  • 获取静态 Token
  • 获取动态 Token
  • 步骤 2:监听登录状态
  • 步骤 3:监听数据同步状态
  • 步骤 4:登录 IM
  • 登录方式概览
  • 方式 1:手动登录
  • 静态 Token 登录
  • 动态 Token 登录
  • 通过第三方回调登录
  • 方式 2:自动登录
  • 相关信息
  • 手动登录错误码
  • 断网重连机制
  • 多端登录与互踢
  • 登录状态转换流程
  • 常见问题
  • 手动登录和自动登录的主要区别是什么?
  • 断线后是否会自动重连?
  • 如何根据产品形态选择 IM 登录方式?