登录 IM
更新时间: 2024/05/27 14:12:07
完成 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 前,请确保已:
实现登录 IM
步骤1:准备 Token
登录 IM 需要通过token
进行鉴权。云信提供静态和动态这两种 token
类型,您可根据业务需求进行选择。
-
静态
token
:默认为永久有效。如有需要,可通过云信服务端 API 主动刷新 Token。 -
动态
token
:具备时效性,可在生成时设置token
的有效期。
获取静态Token
-
方式1:在控制台获取静态 Token
如果您只需要进行简单的体验或者快速测试,那么可以在云信控制台创建测试用的 IM 账号,并获取与该 IM 账号相应的静态
token
。具体参见注册调试用的 IM 账号。获取的静态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
。 -
客户端可通过在初始化时实现
RegReloginRequestToeknCb
方法,从回调中获取动态token
。
动态获取第三方鉴权扩展信息
NIM SDK 也支持获取动态的登录自定义扩展字段 LoginParams::login_ex_
。动态 login_ex_
适用于所有登录模式,其中,在第三方回调登录模式中使用动态 login_ex_
时,第三方服务器可以使用该字段来进行鉴权。
客户端可通过在初始化时实现 RegRequestLoginExtensionCb
方法,从回调中获取动态 login_ex_
。
步骤2:注册相关监听
调用登录接口前,需要先实现监听 IM 登录断开事件和自动重连事件。
监听登录断开事件
注册RegDisconnectCb
回调,监听是否掉线,断开连接。该回调主要用于客户端 UI 刷新。
示例代码如下:
Client::RegDisconnectCb(
[]() {
// process disconnect event
// ......
},
"");
监听自动重连事件
SDK 提供了断网自动重连机制(自动重新建立与网易云信服务器的连接并重新登录),您可以注册RegReloginCb
回调,监听自动重连事件。一些特殊的登录错误需要通过该回调返回,包括 App Key 未设置、参数错误、密码错误、多端登录冲突、账号被封禁、操作过于频繁等,具体请参考NIMResCode
,建议在集成时能尽可能在上层应用考虑应对逻辑。
例如,自动重连时如果用户名和密码不匹配,上层应用需实现登出并提示用户手动登录或是从应用服务器刷新相应的用户名和密码等逻辑。
- 网络状态较差时容易导致自动重连发生网络超时错误,此时上层应用无需处理,SDK 会持续有策略地重连。
- 手动登录阶段有重连次数上限,初始化可配置,默认最多重试三次,三次都失败会触发登录断开事件,此时需要上层重新调用登录接口。登录保持阶段重连无上限,在第一次断开连接时会触发登录断开事件。
步骤3:登录 IM
NIM SDK 登录方式分为静态token
登录、动态token
登录和通过第三方回调登录,分为对应静态 Token 鉴权、动态 Token 鉴权和通过第三方回调鉴权三种鉴权方式。
您可按需实现一种或多种登录方式。
SDK 通过 auth_type_
(NIMAuthType) 来定义鉴权方式:
枚举值 | 对应值 | 说明 |
---|---|---|
kNIMAuthTypeDefault |
0 | 默认登录方式,静态 token 鉴权 |
kNIMAuthTypeBySecretToken |
1 | 使用 App secret 生成的 token 登录,动态 token 鉴权 |
kNIMAuthTypeByAppToken |
2 | 使用第三方回调服务器生成的凭证,第三方回调鉴权 |
静态 Token 登录
调用Login
方法进行手动登录。
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
app_key | std::string | 否 | 您的应用在云信的账号(App Key) 如果不填,则使用初始化时填入 App Key;如果调用本接口时填入,则使用新填入的 App Key |
account | std::string | 是 | 用户的 IM 账号(即accid) |
password | std::string | 是 | 获取到的静态token |
json_extension | std::string | 否 | JSON 扩展参数,主要用于指定登录信息 LoginParams,包括自定义登录数据(custom_data_)、鉴权方式 (auth_type_)以及第三方回调扩展信息(login_ex_)。
|
cb | LoginCallback | 否 | 登录流程的回调函数 |
示例代码如下:
//静态token的模式登录IM
LoginParams login_param;
login_param.auth_type_ = kNIMAuthTypeDefault;
std::string login_param_str;
Client::LoginCustomDataToJson(login_param, login_param_str);
Client::Login("appkey", "accid", "password", [](const LoginRes& res) {
if (res.res_code_ != kNIMResSuccess){
// login failed
} else if (res.login_step_ == kNIMLoginStepLogin){
// login success
}
}, login_param_str);
动态 Token 登录
NIM SDK 支持动态 token
登录这一登录方式。该登录方式的 token
具备时效性,可有效提升 token
破解难度,降低密码泄露风险。
要实现动态登录 IM,需完成如下两步操作:
-
初始化时,实现
RegReloginRequestToeknCb
方法获取上文提及的基于App Secret生成的动态Token。 示例代码如下:Client::RegReloginRequestToeknCb([](std::string* token) { std::string login_token; // get token from your application server // ...... *token = login_token; });
-
调用
Login
方法进行手动登录。参数 类型 必填 说明 app_key std::string 否 您的应用在云信的账号(App Key)
如果不填,则使用初始化时填入 App Key;如果调用本接口时填入,则使用新填入的 App Keyaccount std::string 是 用户的 IM 账号(即accid) password std::string 是 静态 token。当 IM 采用动态 token 鉴权方式登录时,无需提供静态 token
如果您的应用启用了云信的聊天室功能,并且采用非独立模式登录时(调用 ChatRoom::Enter 接口登录聊天室时需要 IM 的静态 token),那么此处需要传入静态 tokenjson_extension std::string 是 JSON 扩展参数,主要用于指定登录信息 LoginParams,包括自定义登录数据(custom_data_)、鉴权方式 (auth_type_)以及第三方回调扩展信息(login_ex_)。 - 动态 token 模式下,auth_type_ 必须设置为 kNIMAuthTypeBySecretToken
- 可通过 LoginCustomDataToJson 接口将 LoginParams 转换为 JSON 格式字符串
cb LoginCallback 否 登录流程的回调函数 示例代码如下:
LoginParams login_param; login_param.auth_type_ = kNIMAuthTypeBySecretToken; std::string login_param_str; Client::LoginCustomDataToJson(login_param, login_param_str); Client::Login("appkey", "accid", "", [](const LoginRes& res) { if (res.res_code_ != kNIMResSuccess){ // login failed } else if (res.login_step_ == kNIMLoginStepLogin){ // login success } }, login_param_str);
通过第三方回调登录
如采用该登录方式,云信服务端不做 IM 登录鉴权,鉴权工作需由指定的第三方服务器(可以是应用服务器)进行。
实现该登录方式,需完成如下 4 步操作:
-
前往云信控制台,并进入IM 即时通讯 > 功能配置 > 第三方回调配置第三方回调的环境地址(即第三方服务器地址)和回调失败时放行(通过)与否。
-
若您的应用需要采用第三方服务器的动态 Token 或者动态第三方回调扩展信息鉴权,那么需要在初始化时实现
RegReloginRequestToeknCb
和RegRequestLoginExtensionCb
方法,SDK 会在登录过程时动态获取第三方回调的动态 Token 和动态扩展字段(login_ex_
)。示例代码如下:
Client::RegReloginRequestToeknCb([](std::string* token) { std::string login_token; // get token from your application server // ...... *token = login_token; }); Client::RegRequestLoginExtensionCb([this](std::string* extension) { std::string login_extension; // get login extension from your application server // ...... *extension = login_extension; });
-
调用
Login
方法进行动态登录。参数 类型 必填 说明 app_key std::string 否 您的应用在云信的账号(App Key)
如果不填,则使用初始化时填入 App Key;如果调用本接口时填入,则使用新填入的 App Keyaccount std::string 是 用户的 IM 账号(即accid) password std::string 是 静态 token。当 IM 采用第三方回调鉴权方式登录时,无需提供静态 token
如果您的应用启用了云信的聊天室功能,并且采用非独立模式登录时(调用 ChatRoom::Enter 接口登录聊天室时需要 IM 的静态 token),那么此处需要传入静态 tokenjson_extension std::string 是 JSON 扩展参数,主要用于指定登录信息 LoginParams,包括自定义登录数据(custom_data_)、鉴权方式 (auth_type_)以及第三方回调扩展信息(login_ex_)。 - 第三方回调模式下,auth_type_ 必须设置为 kNIMAuthTypeByAppToken
- 可通过 LoginCustomDataToJson 接口将 LoginParams 转换为 JSON 格式字符串
cb LoginCallback 否 登录流程的回调函数 示例代码如下:
//第三方鉴权的模式登录IM LoginParams login_param; login_param.auth_type_ = kNIMAuthTypeByAppToken; std::string login_param_str; Client::LoginCustomDataToJson(login_param, login_param_str); Client::Login("appkey", "accid", "", [](const LoginRes& res) { if (res.res_code_ != kNIMResSuccess){ // login failed } else if (res.login_step_ == kNIMLoginStepLogin){ // login success } }, login_param_str);
-
发起登录相关回调的请求,由第三方服务器进行鉴权并判定 IM 登录事件是否放行通过。
若不通过,云信服务端将返回第三方回调错误码
步骤4(可选):主动查询登录状态
调用GetLoginState
方法主动查询当前 IM 账号的登录状态。
返回的登录状态(NIMLoginState
)包括:
kNIMLoginStateLogin
:已登录kNIMLoginStateUnLogin
:未登录
相关信息
登录过程
登录过程中的状态可查看 NIMLoginStep
枚举:
枚举值 | 说明 |
---|---|
kNIMLoginStepLinking |
正在连接服务器 |
kNIMLoginStepLink |
连接服务器成功 |
kNIMLoginStepLogining |
正在登录 |
kNIMLoginStepLogin |
登录成功 |
断网重连
SDK 提供了自动重连机制(自动重新建立与网易云信服务器的连接并重新登录),您可以注册RegReloginCb
回调,监听自动重连事件。
SDK 登录成功后,网络不佳导致 SDK 与云信服务端连接断开时会自动进行重连,不需要上层开发者去做额外的重登逻辑。
重试次数超过预定上限(默认重连 3 次)时,SDK 不会继续重连。可以在初始化参数中(SDKConfig
)自行设置重试次数(login_max_retry_times
)。
多端登录与互踢
当前 NIM SDK 支持配置四种不同的 IM 多端登录与互踢策略,具体参见多端登录与互踢。
相关辅助方法
Client
类中提供了辅助方法:
方法 | 说明 |
---|---|
GetCurrentUserAccount |
获取当前登录的 IM 账号。如果没有登录成功,会返回空字符串"" |
GetServerCurrentTime |
查询云信服务端当前的时间。 |