IM 即时通讯
Android
产品介绍
简介
产品优势
主要功能
功能介绍
帐号集成与登录
群组功能
聊天室功能
聊天室标签功能
圈组功能
多端登录与互踢策略
质量数据监控台
海外数据中心
IM平滑迁移方案
接口及业务限制
更新日志
IM UIKit 更新日志
NIM SDK 开发版更新日志
NIM SDK 稳定版更新日志
体验 Demo
下载 SDK 与 Demo 源码
快速开始
跑通 IM Demo 源码
实现单聊消息收发(不含 UI)
跑通圈组 Demo 源码
实现圈组消息收发(不含 UI)
含 UI 集成
什么是 IM UIKit
IM UIKit 功能概览
快速集成 IM UIKit
组件导入
初始化
界面跳转
自定义用户信息
全局配置
会话列表相关
集成会话列表界面
会话列表事件监听
自定义会话列表界面 UI
会话列表 API 概览
会话消息相关
集成会话界面
会话界面事件监听
实现音视频通话
实现地理位置消息功能(含 UI)
实现自定义消息发送(含 UI)
自定义会话界面 UI
会话消息 API 概览
通讯录相关
集成通讯录界面
自定义通讯录界面 UI
通讯录界面事件监听
通讯录 API 概览
IM UIKit 常见问题排查
IM UIKit API 概览
不含 UI 集成
集成 SDK
初始化
登录相关
登录 IM
多端登录与互踢
登出 IM
消息相关
消息概述
消息收发
自定义消息收发
消息配置选项
NOS 存储场景
广播消息收发
消息已读回执
消息撤回
消息重发与转发
消息更新
消息过滤
语音消息处理
插入本地消息
历史消息
最近会话
服务端会话服务
用户资料
用户关系
在线状态订阅
系统通知
系统通知概述
内置系统通知管理
内置系统通知未读数
自定义系统通知收发
离线推送与消息提醒
群组功能
群组概述
群组管理
群成员管理
群消息管理
超大群功能
聊天室
圈组功能
圈组概述
登录管理
服务器相关
服务器概述
服务器管理
服务器成员管理
游客功能
服务器未读数管理
频道相关
频道概述
频道管理
频道黑白名单
实时互动频道
频道分组
频道分组黑白名单
频道未读数管理
搜索服务器和频道
身份组相关
身份组概述
身份组应用场景
服务器身份组
频道身份组
用户定制权限
频道分组身份组
自定义权限项
成员权限查询与判定
身份组相关查询
圈组订阅机制
圈组消息相关
图解圈组消息流转
圈组消息收发
圈组消息撤回
圈组消息更新
圈组消息删除
消息正在输入
会话消息回复(Thread)
圈组快捷评论
获取频道最后一条消息
查询历史消息
查询@我的消息
圈组消息缓存
圈组消息搜索
圈组系统通知相关
圈组系统通知概述
圈组系统通知收发
圈组系统通知更新
圈组离线推送
圈组内容审核
圈组相关抄送
圈组第三方回调
圈组各端接口命名差异
反垃圾
聊天扩展
其他
最佳实践
IM 登录最佳实践
IM 应用隐私合规
聊天室重要消息投递
API 参考
Android SDK API
Android SDK 状态码
IM 控制台指南
创建应用
注册 IM 账号
升级服务
开通聊天室功能
配置应用客户端标识
常见问题
FAQ
错题集
Android 离线推送
实现离线推送
配置消息的推送属性
设置群消息强制推送
设置推送全局免打扰
设置多端推送策略
集成小米推送
集成华为推送
集成荣耀推送
集成 OPPO 推送
集成 vivo 推送
集成魅族推送
集成谷歌推送(FCM)
消息提醒
实现消息提醒
配置消息提醒功能
设置群消息强制提醒
设置消息提醒文案
定制通知栏显示信息
Android 端推送问题排查
第三方推送厂商的限制说明
服务协议

登录 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等信息。此时,应用服务端需要负责保存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 不由终端用户创建,而是由应用服务端分配,以保证安全性。

前提条件

  • 已完成初始化
  • 已在云信控制台配置应用的 IM 登录策略。如未配置相应的登录策略,可能导致后续调用登录接口时因无登录权限而报错(状态码:403)。
    点击查看如何配置登录策略
    1. 登录云信控制台
    2. 在控制台左侧导航栏选择应用,再进入IM 免费版/专业版 > 功能配置 > 登录策略配置
    3. 勾选需要采用的登录策略(可多选)。
      • 静态 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 登录的鉴权。

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

  2. 基于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 开始同步(正在同步)
  • 同步开始时,SDK 数据库中的数据可能还是旧数据
    • 如果是首次登录,那么 SDK 数据库中还没有数据
    • 重新登录时 SDK 数据库中还是上一次退出时保存的数据
  • 在同步过程中,SDK 数据的更新会通过相应的监听接口发出数据变更通知
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 鉴权
通过第三方回调登录 通过第三方回调鉴权
自动登录 继承手动登录的方式 继承手动登录的鉴权方式 应用被清理后,用户再次点击应用图标启动应用时,无需输入用户名和密码即可完成登录的场景。自动登录需在手动登录成功后使用

推荐在手动登录成功后,将accidtoken保存到本地,方便下次应用启动进行初始化时在SDKOptionsLoginInfo中传入,实现自动登录。更多相关说明,参见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,需完成如下两步操作:

  1. 初始化时,通过SDKOptions#AuthProvidergetToken方法获取上文中提及的基于App Secret生成的动态Token

  2. 调用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 步操作:

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

    第三方回调配置文案优化后.png

  2. 调用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 则视为没有自定义类型
  3. 发起登录相关回调的请求,由第三方服务器进行鉴权并判定 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、accidtoken三者不对应
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 是否接管登录失败后的处理
  • 手动登录:NIM SDK 认为手动登录即是终端用户发起登录的流程,因此在登录失败后(如网络情况不佳、密码错误),NIM SDK 会触发相应回调,并停止重连操作,等待用户再次发起登录操作
  • 自动登录:自动登录失败后仍旧尝试重连,直到登录成功为止(密码错误等情况除外)
云信服务端是否验证当前登录设备的安全性
  • 手动登录:不验证
  • 自动登录:自动登录时,如果当前登录设备不是上一次登录设备,云信服务端会自动禁止其登录,以保证安全性。

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

断线后是否会自动重连?

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

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

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

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

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

如何获取云信服务端当前时间?

可调用MiscService#getServerTime方法获取云信服务端当前的时间戳。该方法的调用有频控限制。如果处于频控限制内,返回的时间为上一次获取时间 + 两次时间的偏移量。

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