登录 IM
更新时间: 2023/03/02 10:45:43
完成 NIM SDK 的初始化之后,用户需要先调用 SDK 的登录接口登录 IM。登录成功后,用户才能正常调用消息和会话等其他 SDK 接口。
本文介绍账号集成与登录的技术原理、实现 IM 登录的流程、IM 登录状态转换流程,以及相关常见问题。
技术原理

IM 的登录与账号集成密切相关。上图展示了应用集成 NIM SDK 后,从账号集成到登录 IM 成功的主要流程:
流程序号 |
说明 |
---|---|
1. | 用户在应用客户端注册用户账号时,由应用服务端向云信服务端发起创建 IM 帐号的请求。 |
2. | IM 帐号创建成功后,云信服务端会返回该 IM 帐号(即accid) 和token 等信息。此时,应用服务端需要负责保存accid 和token 的映射关系。 |
3. | 应用客户端发起登录请求时,先走应用自有的登录验证逻辑,如帐号和密码的验证 |
4. | 验证成功后,应用服务端将与该用户对应的accid 和token 等信息返回给应用客户端。此时,应用客户端需要负责保存accid 和token 的映射关系。 |
5. | 当应用客户端需要调用云信的 IM 服务时,需要先进行token 验证,以登录 IM 服务 |
6. | token 验证成功后,应用客户端登录 IM 服务成功。之后用户便可调用 NIM SDK 的相关接口使用 IM 服务,如进行 IM 消息收发 |
- 终端用户使用云信 IM 服务时,应用本身的用户帐号和云信的 IM 账号(
accid
)彼此独立。云信的 IM 账号只用于云信 IM 服务的鉴权,IM 账号并不等同于应用的用户账号。 - 应用的用户帐号和密码,与云信登录 IM 使用的
accid
和token
完全不一致。accid
和token
不由终端用户创建,而是由应用服务端分配,以保证安全性。
前提条件
- 已完成初始化。
- 已在云信控制台配置应用的 IM 登录策略。如未配置相应的登录策略,可能导致后续调用登录接口时因无登录权限而报错(状态码:403)。
点击查看如何配置登录策略
- 登录云信控制台。
- 在控制台左侧导航栏选择应用,再进入IM 免费版/专业版 > 功能配置 > 登录策略配置。
- 勾选需要采用的登录策略(可多选)。
- 静态 token 登录:使用静态 token 进行 IM 登录鉴权,对应下文提及登录方式中的静态 Token 登录。静态token 恒定不变,且永久有效,除非主动刷新。
- 动态 token 登录:使用动态 token 进行 IM 的登录鉴权(安全性更高)。对应下文提及的登录方式中的动态 Token 登录。 动态 token 可定期变更,可在生成时指定有效期。
- 登录第三方回调:通过第三方回调进行 IM 的登录鉴权。对应下文提及的登录方式中的通过第三方回调登录。
实现登录 IM
步骤1:准备 Token
登录 IM 需要通过 Token 进行鉴权。云信支持静态和动态两种 Token 类型,您可根据业务需求进行选择。
-
静态 Token:默认为永久有效。如有需要,可通过云信服务端 API 主动刷新 Token。
-
动态 Token:具备时效性,可在生成时设置有效期。
获取静态Token
-
方式1:在控制台获取静态Token
如果您只需要进行简单的体验或者快速测试,那么可以在云信控制台创建测试用的 IM 账号,并获取与该 IM 账号相应的静态
token
,具体参见注册调试用的 IM 账号。获取的静态token
可用于下文提及的静态 Token 登录。该方式仅 IM 免费版支持。如已升级为 IM 专业版,则需要调用服务端 API 获取静态
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
(通过下文提及的SDKOptions#AuthProvider
),也要传入静态token
。
步骤2:监听登录状态
调用observeOnlineStatus
方法注册在线状态变化观察者,监听登录状态变化。注册后,观察者(Observer
)的onEvent
回调函数会立即被调用一次,告知观察者当前的登录状态(StatusCode
)。
-
StatusCode
枚举各属性的详细说明和具体转换流程,参见文末的登录状态转换流程。 -
StatusCode
枚举的每个属性包含一个 int 类型的 value 和一个 String 类型的 desc。通过云信 IM 服务端接口封禁 IM 账号时,如果配置了kickNotifyExt
,则会表现在onEvent
回调函数的 desc 变量中。
示例代码如下:
NIMClient.getService(AuthServiceObserver.class).observeOnlineStatus(
new Observer<StatusCode> () {
public void onEvent(StatusCode status) {
//获取状态的描述
String desc = status.getDesc();
if (status.wontAutoLogin()) {
// 被踢出、账号被禁用、密码错误等情况,自动登录失败,需要返回到登录界面进行重新登录操作
}
}
}, true);
步骤3:监听数据同步状态
调用observeLoginSyncDataStatus
方法注册观察者,监听登录后的数据同步状态(LoginSyncStatus
)。
登录 IM 成功后,SDK 会自动同步群信息,离线消息,漫游消息,系统通知等数据。数据同步完成时,整个登录过程才算真正完成。
LoginSyncStatus属性 |
说明 |
---|---|
NO_BEGIN |
未开始同步 |
BEGIN_SYNC |
开始同步(正在同步)
|
SYNC_COMPLETED |
同步完成。SDK 数据库已完成更新 |
示例代码如下:
NIMClient.getService(AuthServiceObserver.class).observeLoginSyncDataStatus(new Observer<LoginSyncStatus>() {
@Override
public void onEvent(LoginSyncStatus status) {
if (status == LoginSyncStatus.BEGIN_SYNC) {
LogUtil.i(TAG, "login sync data begin");
} else if (status == LoginSyncStatus.SYNC_COMPLETED) {
LogUtil.i(TAG, "login sync data completed");
}
}
}, register);
步骤4:登录 IM
登录方式概览
NIM SDK 登录方式分为两大类,即手动登录和自动登录。其中手动登录可进一步分为静态token
登录、动态token
登录和通过第三方回调登录。
您可按需实现一种或多种手动登录方式,并在手动登录成功后,实现自动登录。
登录方式 |
子方式 | 鉴权方式 | 使用场景 |
---|---|---|---|
手动登录 | 静态 Token 登录 | 静态 Token 鉴权 | 如下登录场景,用户需要手动登录 IM: |
动态 Token 登录 | 动态 Token 鉴权 | ||
通过第三方回调登录 | 通过第三方回调鉴权 | ||
自动登录 | 继承手动登录的方式 | 继承手动登录的鉴权方式 | 应用被清理后,用户再次点击应用图标启动应用时,无需输入用户名和密码即可完成登录的场景。自动登录需在手动登录成功后使用 |
推荐在手动登录成功后,将accid
和token
保存到本地,方便下次应用启动进行初始化时在SDKOptions
的LoginInfo
中传入,实现自动登录。更多相关说明,参见IM 登录最佳实践。您也可以参考该文档中提供的 Sample Code 实现 IM 登录。
方式1:手动登录
静态 Token 登录
调用AuthService#login
方法手动登录 IM。调用时需将authType
参数设置为 0。
调用后,NIM SDK 会自动连接云信服务端,传递用户信息,返回登录结果。登录过程中可主动取消登录。如果因为网络或其他原因导致云信服务端长时间未响应,用户也没有主动取消登录,NIM SDK 将在 45 秒后自动重新连接云信服务端,并返回错误码,错误码详情参见下文的手动登录错误码。
LoginInfo 参数 |
是否必传 | 说明 |
---|---|---|
account |
是 | 用户的 IM 账号,即accid |
token |
是 | 获取到的静态token |
authType |
否 | 登录 IM 的鉴权方式。采用静态token 登录时,使用默认的 0 即可,即静态token 鉴权 |
appKey |
否 | 当前应用的 App Key,一个 App Key 对应一个账号体系SDKOptions 中配置的 App Key;如果SDKOptions 中未配置,则使用 AndroidManifest 中配置的 App Key。 |
customClientType |
否 | 自定义客户端类型,小于或等于 0 则视为没有自定义类型 |
示例代码如下:
public class LoginActivity extends Activity {
public void doLogin() {
LoginInfo info = new LoginInfo();
RequestCallback<LoginInfo> callback =
new RequestCallback<LoginInfo>() {
@Override
public void onSuccess(LoginInfo param) {
LogUtil.i(TAG, "login success");
// your code
}
@Override
public void onFailed(int code) {
if (code == 302) {
LogUtil.i(TAG, "账号密码错误");
// your code
} else {
// your code
}
}
@Override
public void onException(Throwable exception) {
// your code
}
};
//执行手动登录
NIMClient.getService(AuthService.class).login(info).setCallback(callback);
}
}
动态 Token 登录
自 v8.3.0 版本起,NIM SDK 新增动态token
登录这一登录方式。动态token
具备时效性,可有效提升token
破解难度,降低密码泄露风险。
要实现动态token
登录 IM,需完成如下两步操作:
-
初始化时,通过
SDKOptions#AuthProvider
的getToken
方法获取上文中提及的基于App Secret生成的动态Token。 -
调用
AuthService#login
方法手动登录 IM,调用时需将authType
设置为 1。调用后,NIM SDK 会自动连接云信服务端,传递用户信息,返回登录结果。登录过程中可主动取消登录。如果因为网络或其他原因导致云信服务端长时间未响应,用户也没有主动取消登录,NIM SDK 将在 45 秒后自动重新连接云信服务端,并返回错误码,错误码详情参见下文的手动登录错误码。
具体参数说明如下:
LoginInfo
参数是否必传 说明 account
是 用户的 IM 账号,即 accid
authType
该登录方式必传 采用动态 token
登录时必须传入 1,表示通过动态token
鉴权,动态token
基于 App Secret 计算生成token
视情况而定 获取到的静态 token
。采用动态token
登录时,如果您的应用不需要调用云信的聊天室能力,那么不需要传入静态token
;如果需要,那么必须传入静态token
appKey
否 当前应用的 App Key,一个 App Key 对应一个账号体系 如果不填,则优先使用初始化时 SDKOptions
中配置的 App Key;如果SDKOptions
中未配置,则使用AndroidManifest
中配置的 App Key。customClientType
否 自定义客户端类型,小于或等于 0 则视为没有自定义类型
通过第三方回调登录
如采用该登录方式,云信服务端不做 IM 登录鉴权,鉴权工作需由指定的第三方服务器(可以是应用服务器)进行。
实现该登录方式,需完成如下 3 步操作:
-
前往云信控制台,并进入IM 免费版/专业版 > 功能配置 > 第三方回调配置第三方回调的环境地址(即第三方服务器地址)和回调失败时放行(通过)与否。
-
调用
AuthService#login
方法手动登录 IM,调用时authType
必须传入 2,且必须传入loginExt
。调用后,NIM SDK 会自动连接云信服务端,传递用户信息,返回登录结果。登录过程中可主动取消登录。如果因为网络或其他原因导致云信服务端长时间未响应,用户也没有主动取消登录,NIM SDK 将在 45 秒后自动重新连接云信服务端,并返回错误码,错误码详情参见下文的手动登录错误码。具体参数说明如下:
LoginInfo
参数是否必传 说明 account
是 用户的 IM 账号,即 accid
authType
该登录方式必传 登录 IM 的鉴权方式,采用该登录方式时必须传入 2,表示通过第三方回调进行鉴权 loginExt
该登录方式必传 登录自定义扩展字段。采用该登录方式时,必须传入,用于第三方服务器鉴权。如未传入,将返回 LoginInfo is invalid
的报错信息。token
视情况而定 静态 token
。通过第三方回调登录时,如果您的应用不需要调用云信的聊天室能力,那么不需要传入静态token
;如果需要,那么必须传入静态token
。appKey
否 当前应用的 App Key,一个 App Key 对应一个账号体系 如果不填,则优先使用初始化时 SDKOptions
中配置的 App Key;如果SDKOptions
中未配置,则使用AndroidManifest
中配置的 App Key。customClientType
否 自定义客户端类型,小于或等于 0 则视为没有自定义类型 -
发起登录相关回调的请求,由第三方服务器进行鉴权并判定 IM 登录事件是否放行通过。
若不通过,云信服务端将返回 302 错误码。
方式2:自动登录
自动登录一般用于应用被清理后,用户再次点击应用图标启动应用时,无需输入用户名和密码即可完成登录的场景。此时应用可以在无网络、未登录成功的状态下直接访问用户本地 SDK 数据。自动登录与手动登录在客户端侧和服务端逻辑上的区别,参见文末的常见问题。
实现自动登录的方式为,在调用初始化的几个方法时,传入LoginInfo
。
推荐参考自动登录最佳实践和登录状态处理最佳实践实现自动登录以及相应的登录状态处理逻辑。
示例代码如下(仅以调用NIMClient#init
方法为例):
public class NimApplication extends Application {
public void onCreate() {
// ... your codes
NIMClient.init(this, loginInfo(), options());
// ... your codes
}
private LoginInfo loginInfo() {
// 从本地读取上次登录成功时保存的用户登录信息
String account = Preferences.getUserAccount();
String token = Preferences.getUserToken();
if (!TextUtils.isEmpty(account) && !TextUtils.isEmpty(token)) {
DemoCache.setAccount(account.toLowerCase());
return new LoginInfo(account, token);
} else {
return null;
}
}
}
步骤5(可选):主动查询登录状态
SDK支持通过StatusCodeInfo#getStatus
方法主动查询当前账号是否处于在线状态。
返回当前用户的登录的状态枚举值说明,请参见下文的登录状态转换流程。
示例代码:
if (NIMClient.getStatus() == StatusCode.LOGINED) {
……;
}
相关信息
手动登录错误码
手动登录的错误码通过onFailed
回调返回,具体如下:
错误码 | 说明 |
---|---|
302 | App Key、accid 和token 三者不对应 |
408 | 连接超时 |
415 | 网络断开或者连接云信服务端失败 |
416 | 调用频次过高 |
1000 | 本地数据库未打开。请在手动登录成功后打开本地数据库 |
断网重连机制
SDK 提供了自动重连机制(自动重新建立与云信服务端的连接并重新登录),所有重连的登录状态变更都会在observeOnlineStatus
方法中回调。
SDK 在两种场景下会自动进行重连:
- 手动/自动登录成功后,网络不佳导致连接断开的情况。
- 网络不佳时,账号密码本身正常(未被封禁,且账号密码均正确),启动应用时调用自动登录接口的情况。
满足上述中一个条件,当用户遇到普通网络问题如连接超时等,会自动进行重连登录,不需要上层开发者去做额外的重登逻辑。
多端登录与互踢
当前 NIM SDK 支持配置四种不同的 IM 多端登录与互踢策略,具体参见多端登录与互踢。
离线查看数据
对于一些弱 IM 场景,需要在登录成功前或者未登录状态下访问指定账号的数据(聊天记录、好友资料等)。
SDK 提供两种方案:
-
使用自动登录。在登录成功前,可以访问 SDK 服务来读取本地数据(但不能发送数据)。
-
在手动登录成功前(可能由于网络问题,登录时间较长),调用
AuthService#openLocalCache
方法在离线时打开本地数据。这是一个同步方法,打开后即可读取 SDK 数据库中的记录。可以通过注销来切换账号查看本地数据。
登录状态转换流程

登录状态(StatusCode) |
说明 |
---|---|
INVALID |
未定义 |
UNLOGIN |
未登录/登录失败。登录成功之后,如果触发了 UNLOGIN 回调,不需要尝试重新手动登录,SDK 内部有自动重连逻辑 |
NET_BROKEN |
网络连接已断开 |
CONNECTING |
正在连接云信服务端 |
LOGINING |
正在登录中 |
SYNCING |
正在同步数据,登录成功后开始同步 |
LOGINED |
已成功登录 |
KICKOUT |
被其他端的登录踢下线,此时应该跳转至手动登录界面。具体机制参见多端登录与互踢策略。被踢后,无法自动登录 |
KICK_BY_OTHER_CLIENT |
被同时在线的其他端主动踢下线(通过kickOtherClient 方法),此时应该跳转至手动登录界面。被踢后,无法自动登录 |
FORBIDDEN |
被服务器禁止登录(云信 IM 账号被禁用)。被禁止登录后,无法自动登录 |
VER_ERROR |
SDK 版本错误。出现该登录异常后,无法自动登录 |
PWD_ERROR |
云信 IM 账号(accid)或 Token 错误。出现该登录异常后,无法自动登录 |
DATA_UPGRADE |
数据库需要迁移到加密状态(类似被踢出、云信 IM 账号被禁用、Token 错误等情况。如自动登录失败,需要返回到登录界面进行重新登录操作) |
常见问题
手动登录和自动登录的主要区别是什么?
手动登录和自动登录主要在于:
差异点 |
说明 |
---|---|
NIM SDK 是否接管登录失败后的处理 |
|
云信服务端是否验证当前登录设备的安全性 |
|
如您选择自动登录,当您的应用在后台被唤起时,会计算为1次登录行为,计入日活统计作为计费依据。
断线后是否会自动重连?
一旦登录成功后(或者调用过自动登录),NIM SDK 将接管所有的重连情况:在网络正常的情况下不停重试重连直到正常登录为止,并不需要做额外的登录操作(聊天室同理)。
如何根据产品形态选择 IM 登录方式?
接入网易云信 IM 服务的产品大致分为两种形态:
- IM 产品:通讯作为其核心模块。典型例子如微信、易信、网络直播相关应用。
- 非 IM 产品:通讯只是其附带模块,典型例子如各种有私信模块的应用。
对于 IM 产品,由于通讯能力是核心能力,如果云信无法登录成功则整个应用将无法正常表现,所以推荐在执行业务逻辑前,首先完成应用服务端和云信服务端的登录。只有应用服务端和云信服务端都登录成功才认为整个登录完成。而对于非 IM 产品而言,通讯能力是可以在登录应用服务端成功后延迟加载,登录成功拿到服务端下发的云信 IM 账号和 token
后进行自动登录即可。
如何获取云信服务端当前时间?
可调用MiscService#getServerTime
方法获取云信服务端当前的时间戳。该方法的调用有频控限制。如果处于频控限制内,返回的时间为上一次获取时间 + 两次时间的偏移量。