登录 IM
更新时间: 2024/08/13 15:37:24
完成 NIM SDK 的初始化之后,您需要先调用 SDK 的登录接口登录 IM。登录成功后,您才能正常调用消息和会话等其他 SDK 接口。
本文介绍账号集成与登录的技术原理、实现 IM 登录的流程、IM 登录状态转换流程,以及 相关常见问题。
技术原理
IM 的登录与账号集成密切相关。上图展示了应用集成 NIM SDK 后,从账号集成到登录 IM 成功的主要流程:
- 用户在应用客户端注册用户账号时,由应用服务端向网易云信服务端发起 创建 IM 账号 的请求。
- IM 账号创建成功后,网易云信服务端会返回该 IM 账号(即
accid
)和token
等信息。此时,应用服务端需要负责保存accid
和token
的映射关系。 - 应用客户端发起登录请求时,先走应用自有的登录验证逻辑,如账号和密码的验证。
- 验证成功后,应用服务端将与该用户对应的
accid
和token
等信息返回给应用客户端。此时,应用客户端需要负责保存accid
和token
的映射关系。 - 当应用客户端需要调用网易云信的 IM 服务时,需要先进行
token
验证,以登录 IM 服务。 token
验证成功后,应用客户端登录 IM 服务成功。之后用户便可调用 NIM SDK 的相关接口使用 IM 服务,如进行 IM 消息收发。
- 终端用户使用网易云信 IM 服务时,应用本身的用户账号和网易云信的 IM 账号(
accid
) 彼此独立。网易云信的 IM 账号只用于网易云信 IM 服务的鉴权,IM 账号并不等同于应用的用户账号。 - 应用的用户账号和密码,与网易云信登录 IM 使用的
accid
和token
完全不一致。accid
和token
不由终端用户创建,而是由应用服务端分配,以保证安全性。
前提条件
- 已完成 初始化。
- 已在 网易云信控制台 配置应用的 IM 登录策略。如未配置相应的登录策略,可能导致后续调用登录接口时因无登录权限而报错(状态码:403)。
- (可选)已在 网易云信控制台 配置客户端应用标识。
API 调用时序
下图展示了与用户首次登录登出相关的 API 的调用时序,图中的 NIM 表示 NIM Flutter SDK。
步骤 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 登录 的鉴权。
-
注册网易云信 IM 账号,获取 IM 账号(
accid
)和静态token
。 -
基于 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:
|
动态 Token 登录 | 动态 Token 鉴权 | ||
通过第三方回调登录 | 通过第三方回调鉴权 | ||
自动登录 | 继承手动登录的方式 | 继承手动登录的鉴权方式 | 应用被清理后,用户再次单击应用图标启动应用时,无需输入用户名和密码即可完成登录的场景。自动登录需在手动登录成功后使用 |
推荐 在手动登录成功后,将 accid
和 token
保存到本地,方便下次应用启动进行初始化时,在 NIMSDKOptions
的 autoLoginInfo
中传入,实现自动登录。更多相关说明,参考 IM 登录最佳实践。
方式 1:手动登录
静态 Token 登录
调用 login
方法手动登录 IM。调用时需将 authType
参数设置为 authTypeDefault
。
调用后,NIM SDK 会自动连接网易云信服务端,传递用户信息,返回登录结果。登录过程中可主动取消登录。如果因为网络或其他原因导致网易云信服务端长时间未响应,用户也没有主动取消登录,NIM SDK 将在 45 秒后自动重新连接网易云信服务端,并返回错误码,错误码详情参考下文的 手动登录错误码。
NIMLoginInfo 参数 |
是否必传 | 说明 |
---|---|---|
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,需完成如下两步操作:
-
通过
AuthService#dynamicTokenProvider
方法获取上文中提及的基于 App Secret 生成的动态 Token。 -
调用
login
方法手动登录 IM,调用时需将authType
设置为 authTypeDynamic。调用后,NIM SDK 会自动连接网易云信服务端,传递用户信息,返回登录结果。登录过程中可主动取消登录。如果因为网络或其他原因导致网易云信服务端长时间未响应,用户也没有主动取消登录,NIM SDK 将在 45 秒后自动重新连接网易云信服务端,并返回错误码,错误码详情参考下文的 手动登录错误码。
具体参数说明如下:
NIMLoginInfo
参数是否必传 说明 account
是 用户的 IM 账号,即 accid
authType
该登录方式必传 采用动态 token
登录时必须传入 authTypeDynamic,表示通过动态token
鉴权,动态token
基于 App Secret 计算生成token
视情况而定 获取到的静态 token
。采用动态token
登录时,如果您的应用不需要调用网易云信的聊天室能力,那么不需要传入静态token
。如果需要,那么必须传入静态token
customClientType
否 自定义客户端类型,小于或等于 0 则视为没有自定义类型 示例代码如下:
Dart
NimCore.instance.authService.dynamicTokenProvider = (account) async { //...生成动态 token return token; }; loginResult = await NimCore.instance.authService.login(NIMLoginInfo( account: account, token: token, authType: NIMAuthType.authTypeDynamic, ));
通过第三方回调登录
如采用该登录方式,网易云信服务端不做 IM 登录鉴权,鉴权工作需由指定的第三方服务器(可以是应用服务器)进行。
实现该登录方式,需完成如下 3 步操作:
-
前往网易云信控制台,并进入 IM 即时通讯 > 功能配置 > 第三方回调 配置第三方回调的环境地址(即第三方服务器地址)和回调失败时放行(通过)与否。
-
调用
login
方法手动登录 IM,调用时需将authType
设置为 authTypeThirdParty,且必须传入loginExt
。调用后,NIM SDK 会自动连接网易云信服务端,传递用户信息,返回登录结果。登录过程中可主动取消登录。如果因为网络或其他原因导致网易云信服务端长时间未响应,用户也没有主动取消登录,NIM SDK 将在 45 秒后自动重新连接网易云信服务端,并返回错误码,错误码详情参考下文的 手动登录错误码。
具体参数说明如下:
NIMLoginInfo
参数是否必传 说明 account
是 用户的 IM 账号,即 accid
。authType
该登录方式必传 采用第三方回调登录时必须传入 authTypeThirdParty
,表示通过第三方回调进行鉴权。loginExt
该登录方式必传 登录自定义扩展字段,长度上限为 1k 字符。采用该登录方式时,必须传入,用于第三方服务器鉴权。如未传入,将返回 LoginInfo is invalid
的报错信息。token
视情况而定 获取到的静态 token
。采用动态token
登录时,如果您的应用不需要调用网易云信的聊天室能力,那么不需要传入静态token
。如果需要,那么 必须传入 静态token
。customClientType
否 自定义客户端类型,小于或等于 0 则视为没有自定义类型。 -
发起 登录相关回调 的请求,由第三方服务器进行鉴权并判定 IM 登录事件是否放行通过。
若不通过,网易云信服务端将返回 302 错误码。
方式 2:自动登录
自动登录一般用于应用被清理后,用户再次单击应用图标启动应用时,无需输入用户名和密码即可完成登录的场景。此时应用可以在无网络、未登录成功的状态下直接访问用户本地 SDK 数据。自动登录与手动登录在客户端侧和服务端逻辑上的区别,参考文末的 常见问题。
实现自动登录的方式为,在调用 initialize
方法初始化 SDK 时,将本地保存的 account
和 token
传入 NIMAndroidSDKOptions
或 NIMIOSSDKOptions
的自动登录信息(autoLoginInfo
)。
- 推荐 参考 自动登录最佳实践 和 登录状态处理最佳实践 实现自动登录以及相应的登录状态处理逻辑。
- 目前仅 Android 和 iOS 支持自动登录,Windows 和 macOS 不支持。
示例代码如下:
DartNimCore.instance.initialize(
NIMAndroidSDKOptions(
appKey: 'appkey',
autoLoginInfo: NIMLoginInfo(
account: 'account',
token: 'token',
),
),
).then(
(result) {
if (result.isSuccess) {
/// 初始化成功
} else {
/// 初始化失败
}
},
);
相关信息
手动登录错误码
手动登录失败的错误码说明如下:
错误码 | 说明 |
---|---|
302 | App Key、accid 和 token 三者不对应 |
408 | 与网易云信服务端的连接超时 |
415 | 网络断开或者连接网易云信服务端失败 |
416 | 调用手动登录接口过于频繁 |
1000 | 本地数据库未打开。请在手动登录成功后打开本地数据库 |
断网重连机制
SDK 提供了自动重连机制(自动重新建立与网易云信服务端的连接并重新登录),所有重连的登录状态变更都会触发 NIMAuthStatusEvent
事件回调。
SDK 在两种场景下会自动进行重连:
- 手动/自动登录成功后,网络不佳导致连接断开的情况。
- 网络不佳时,账号密码本身正常(未被 封禁,且账号密码均正确),启动应用时调用自动登录接口的情况。
满足上述中一个条件,当用户遇到普通网络问题如连接超时等,会自动进行重连登录,不需要上层开发者去做额外的重登逻辑。
多端登录与互踢
当前 NIM SDK 支持配置四种不同的 IM 多端登录与互踢策略,具体参考 多端登录与互踢。
登录状态转换流程
登录状态变化流程(不包含被踢下线和被 IM 服务端禁止登录等特殊状态)参考下图。图中,深蓝色元素代表登录状态,浅绿色元素代表自动登录或调用 login
方法的手动登录。
常见问题
手动登录和自动登录的主要区别是什么?
手动登录和自动登录主要在于:
差异点 |
说明 |
---|---|
NIM SDK 是否接管登录失败后的处理 |
|
网易云信服务端是否验证当前登录设备的安全性 |
|
如您选择自动登录,当您的应用在后台被唤起时,会计算为 1 次登录行为,计入日活统计作为计费依据。
断线后是否会自动重连?
一旦登录成功后(或者调用过自动登录),NIM SDK 将接管所有的重连情况:在网络正常的情况下不停重试重连直到正常登录为止,并不需要做额外的登录操作(聊天室同理)。
如何根据产品形态选择 IM 登录方式?
接入网易云信 IM 服务的产品大致分为两种形态:
- IM 产品:通讯作为其核心模块。典型例子如微信、易信、网络直播相关应用。
- 非 IM 产品:通讯只是其附带模块,典型例子如各种有私信模块的应用。
对于 IM 产品,由于通讯能力是核心能力,如果网易云信无法登录成功则整个应用将无法正常表现,所以推荐在执行业务逻辑前,首先完成应用服务端和网易云信服务端的登录。只有应用服务端和网易云信服务端都登录成功才认为整个登录完成。而对于非 IM 产品而言,通讯能力是可以在登录应用服务端成功后延迟加载,登录成功拿到服务端下发的网易云信 IM 账号和 token
后进行自动登录即可。