全民K歌IOT开放平台
  1. 开放平台接入指南
全民K歌IOT开放平台
  • 厂商合作流程
  • 快速接入K歌开放平台流程
  • SDK bug提单规范
  • 如何在线调试接口
  • 常见问题FAQ
  • 开放平台API错误码说明
  • 开放平台接入指南
    • 登录鉴权方式介绍V2(推荐)
    • 如何申请接入
    • CDK权限申请流程
    • 暗账号绑定明账号对接文档
    • 全民K歌暗账号登录方案
    • 获取应用级token
      POST
    • 获取登录二维码
      POST
    • 查询二维码的状态
      POST
    • 获取用户级token
      POST
    • 刷新用户级token
      POST
    • 暗账号解绑K歌uid
      POST
    • 获取暗账号绑定信息
      POST
  • KtvSDK3.0接入说明
    • KtvSDK-接入指南
    • KtvSDK-打分
    • KtvSDK-登录
    • KtvSDK-歌词
    • KtvSDK-播放
    • 作品录音、合成与播放2.0版
    • KtvSDK-播放页实现示例
    • KtvSDK-常见问题FAQ
    • KtvSDK-低性能设备处理
    • KtvSDK-反馈
    • KtvSDK-缓存管理
    • KtvSDK-切换音频视频清晰度
    • KtvSDK-跳过前奏
    • Ktv支付-米大师支付
    • 播放失败错误码说明
    • KtvSDK-3.0版本新功能
    • KtvSDK-2.0升级到3.0版本迁移指南
    • KtvSDK-多屏渲染
    • 多屏一起唱---歌词与打分适配
    • KtvSDK-Android4.4设备G2证书兼容处理
  • 基础类
    • tagId对照表
    • 歌曲详情
    • 查询mv的播放地址
    • 搜索
    • 搜索联想
    • 查询歌手歌曲
    • 获取歌曲歌词文件
    • Q音歌曲mid映射K歌
    • 短剧播放链接
    • 查询应用限免配置
    • 转换Q音或酷狗歌曲ID
  • 运营类
    • 排行榜id说明
    • 获取城市id列表
    • 获取专题分类列表
    • 获取云端配置
    • 热门ugc
    • 热搜词
    • 排行榜
    • 获取专题下歌曲信息
    • 获取车联渠道映射
    • 热门推荐
    • (新)排行榜
    • 综合歌单列表查询
    • 设置缓存设备
    • TV版分类歌单列表
    • 获取用户协议
    • 综合歌单列表查询(海外)
    • 榜单列表查询(海外)
    • 自建歌单列表查询(海外)
    • 获取广告配置
    • 拉取短剧合集的列表
  • 用户类
    • 用户信息查询
    • 删除用户UGC作品
    • 获取推荐/翻唱作品
    • 获取同城作品
    • 用户作品列表
    • 获取好友作品
    • UGC作品详情
    • 更改作品访问权限
    • 用户个推歌单
  • 支付类
    • 支付接入流程
    • 订单发货使用简述
    • 开通设备会员限免简述
    • 订单发货中通用sign计算规则
    • 通用返回结构
    • 【CDK】CDK兑换
    • 【CDK】生成CDK
    • 【CDK】CDK召回
    • 【CDK】CDK状态查询
    • 【三方支付】订单发货
    • 【三方支付】手机号发货
    • 【三方支付】订单状态查询
    • 【米大师支付】获取会员商品列表
    • 【米大师支付】未登录-查询会员商品列表
    • 【米大师支付】支付下单
    • 【米大师支付】支付成功通知
    • 【米大师支付】查询用户支付成功订单记录
    • 查询设备以及用户是否有赠送资格
    • 查询设备限免剩余时长
    • 设备会员迁移
    • 查询会员赠送时长
    • 同步支付订单接口
    • 【三方支付】存量会员迁移领取查询
    • 【三方支付】存量会员迁移接口
    • 授权设备体验会员
    • 查询用户会员信息
    • 【三方支付】超会发货
    • 取消授权设备体验会员
  • 用户作品-文件类
    • callback_url说明
    • 上传音频源文件
    • (服务端)上传音频作品的链接
  • 通用类
    • 【厂商定制】匹配搜索
    • 获取kg的短链接
  1. 开放平台接入指南

全民K歌暗账号登录方案

全民K歌暗账号登录方案#

一、概述#

全民K歌支持通过第三方账号,生成K歌的暗账号,实现静默登录的功能,也可让用户无需绑定K歌账号即可购买会员,并将权益下发到暗账号。
暗账号登录与微信/QQ扫码登录区别:
1.
暗账号可实现静默登录,从而实现与三方账号的绑定,但它本身没有真实的K歌账号。
2.
因为没有真实的K歌账号,所以无法使用用户资产相关的接口。比如上传/查询用户作品、个性化推荐接口。
注:此权限需要单独开通,找K歌产品沟通(K歌产品需在开通appid单独说明,并在内部"开放平台对接记录"表标明是登录方式为"暗账号登录")。

二、名称解释#

名词描述备注
userId第三方账号id
loginToken暗账号登录临时凭证有有效期,建议10分钟内有效
建议生成方法:由"userId+时间戳"加密后生成,使用AES256加密
openIdK歌暗账号idopenId与userId需要一一对应,不允许有一对多的关系

三、登录流程#

为什么不直接使用userId进行SDK登录:
userId一般不可变,比较容易泄露,并且泄露后也很难封禁。如果userId泄露出去,破解者就可能伪造sdk集成方的身份来进行sdk登录,进而使用K歌的服务,对sdk集成方造成成本损失。
而loginToken与userId不同:
1.
由loginToken不能反推出真实的userId。
2.
sdk登录过程中,只需要loginToken,userId在sdk完全不可见,没有泄漏的可能。
3.
loginToken有有效期,并且有效期很短。
基于以上几点,可知即使loginToken被非法获取到,影响也有限。

四、暗账号认证接口(后台使用)#

对应上图中的步骤6-8,对接暗账号登录,通过业务方提供的授权token,返回对应的暗账号ID。由业务方后台实现
请求方式
POST
Header参数
参数名必选说明
Content-Type是固定填 application/json
请求body(json)
参数名必选类型说明
appid是string应用appid
token是string第三方授权token
// 成功
{
    "error_code": 0,
    "error_msg": "",
    "data": {
        "user_id": 239120823449,
    }
}

// 失败
{
    "error_code": 1003,       
    "error_msg": "Expired"
}
返回参数说明
参数名类型说明
error_codenumber错误码. 非0为失败
error_msgstringerror_code非0时的错误消息
dataObject
user_idnumber暗账号ID
user_sidstring暗账号ID(字符串型,部分应用支持.)
错误码说明
错误码说明
0成功
1001系统异常
1002参数异常
1003授权过期

五、查询第三方账号对应的暗账号openid接口(后台使用)#

如果业务方需要用(暗账号)虚拟账号id,来获取对应的openid,可用此接口。由K歌实现。
请求URL
正式环境:https://api.kg.qq.com/api/v2/get_virtual_openid
测试环境:https://api.kg.qq.com/test/api/v2/get_virtual_openid
请求方式
POST
参数
body: json格式
参数名必选类型说明
appid是string业务透传过来,应用appid
id是number用户id,数字类型
sid是string用户字符串型id (与id只传一个. 使用字符串型id需要特殊申请)
access_token是string应用的access_token
access_token可使用获取应用级access_token 获取,不需要sdk也得获取。也可使用sdk登录后的用户级access_token.
请求示例
{
    "appid": "abc",
    "access_token": "abc",
    "id": 9238283,
}
返回示例
// 成功
{
    "error_code": 0,
    "error_msg": "",
    "openid": "xxxxx",
}

// 失败
{
    "error_code": 3003,
    "error_msg": "Sign check failed"
}
返回参数说明
参数名类型说明
openidstring对应账号的openid
error_codeint错误码
error_msgstringerror_code非0时的错误消息
错误码说明
错误码说明
0成功
1503未知错误
3001参数无效或者参数不完整
3003签名错误(应用token校验失败)
3019暂不支持(应用无权限调用)

六、暗账号登录接口(客户端使用)#

在暗账号登录方案中,KtvSDK对应的登录接口如下:
以下接口在KtvLoginService类中。
接口描述
void hiddenAccountLogin(code: String, loginAPI: IKLoginAPI)暗帐号登录;code:loignToken,loginAPI:登录事件回调
void anonymouslyLogin(loginAPI: IKLoginAPI)游客态帐号登录;loginAPI:登录事件回调
void clearAccessToken()清除登录token
void cancel(loginAPI: IKLoginAPI, isRelease: Boolean)取消登录,isRelease:是否取消登录事件监听,默认true
void cancel(loginAPIs: ArrayList<IKLoginAPI?>, isRelease: Boolean)取消登录,同时取消多个登录监听
void loginOut()退出登录,同时会取消非持久性的登录监听
bindForever(loginAPI: IKLoginAPI)绑定持久化的SDK登录事件回调,在调用loginOut后也不会被取消,适用于需要全局监听登录状态的场景
isLogin()是否有有效的登录token,并不代表已登录
bind(loginAPI: IKLoginAPI)绑定SDK登录事件回调,在loginOut后此监听会被取消

6.1 暗帐号登录#

具体使用见demo的"暗帐号登录"部分。在启动时,如果当前未登录,则直接调用暗帐号登录接口,否则只需调用bind()接口接收登录回调。
暗帐号登录接口,接入方传入当前的渠道名,loginToken,登录状态回调,以下代码是一个简单示例:
对于暗帐号登录的场景,接入方只需要关注LoginSuccess和LoginError事件:
登录成功回调LoginToken(val refreshToken: String, val openId: String, var overTimeMs: Long = 0L)
其中overTimeMs是token的过期时间,sdk会在token过期时通过refrshToken刷新token实现续期,接入方不需要处理。如果刷新失败或者refrshToken过期,返回对应的错误码,需要接入方重新登录;

6.1.1 暗帐号错误码处理#

登录失败时回调错误码和错误信息。
object HiddenAccountLoginManager : IKLoginAPI {
    private val mHandler = Handler(Looper.getMainLooper())
    
    override fun dispatchLoginEvent(loginEvent: LoginEvent) {
        Log.i("HiddenAccountLogin", "dispatchLoginEvent :$loginEvent")
        when (loginEvent) {
            is LoginEvent.LoginSuccess -> {
                //登录成功
                 onLoginSuccess(loginEvent.loginParams, loginEvent.tokenInfo)
            }

            is LoginEvent.AlreadyLogin -> {
                //已废弃,接入方无需关注;
                //在已登录重新触发登录时会触发此回调,或者在已登录时通过sdk进行网络请求时也会触发此回调
            }

            is LoginEvent.RefreshTokenSuccess -> {
                //在refresh_token有效时(默认一个月),sdk会在access_token失效时(默认两个小时)主动刷新token
                //token刷新成功后回调,正常情况接入方也不需要关注
            }
            is LoginEvent.LoginError -> {
                //登录监听最好是全局单例类, 登录失败有两种情况:
                // 1。主动调用登录(loginEvent.activelylogin=true);
                // 2。请求网络时接口token状态异常需要重新登录(loginEvent.activelyLogin=false)
 
                //如果在登录期间有接口请求,接口请求时可能会触发token刷新,在token刷新不成功时会回调登录失败(activelylogin为false)。
        // 为避免这种情况,可以判断如果正在登录,可忽略此类型的登录失败。
        if((mIsLoginRunning.get() || mIsAnonymousLoginRunning.get()) && !loginParams.activelyLogin) {
            Logger.i(TAG, "login is running, ignore LoginError by activelyLogin(false)")
            return
        }
                
                //暗帐号或者游客态登录失败,接入方可以做少量重试操作,具体错误码定义见文档

                val code = loginEvent.exception?.errorCode?: -1
                val msg = loginEvent.exception?.throwable?.message
                mHandler.post {
                    Toast.makeText(
                        HostApp.getApp,
                        "登录失败: 错误码:$code ,错误信息: $msg",
                        Toast.LENGTH_SHORT
                    ).show()
                }
                //以下是具体的错误码示例
                when (code) {
                    SDKLoginError.REFRESH_TOKEN_NULL -> {
                        //网络请求时,token失效了需要刷新token,但refresh_token也为空了,(比如已退出登录,或者多设备登录(40004),或者数据被清空了,导致刷新token为空)
                        //可以重新登录
                        KtvLoginService.hiddenAccountLogin("demo", "testCode", this)
                    }
                    SDKLoginError.REFRESH_TOKEN_EXPIRED -> {
                        //网络请求时,token失效了需要刷新token,但refresh_token过期了(比如超过一个月了)
                        //可以重新登录
                        KtvLoginService.hiddenAccountLogin("demo", "testCode", this)
                    }
                    SDKLoginError.REFRESH_TOKEN_ERROR_UNKNOWN -> {
                        //暗帐号请求刷新token接口失败
                        //可以重新登录试下,需要控制频次 不要一直重复
                        KtvLoginService.hiddenAccountLogin("demo", "testCode", this)
                    }
                    SDKLoginError.HIDDEN_ACCOUNT_LOGIN_FAIL -> {
                        //暗帐号登录 请求登录接口失败
                        //可以重新登录试下,需要控制频次 不要一直重复
                        KtvLoginService.hiddenAccountLogin("demo", "testCode", this)
                    }
                    SDKLoginError.ANONYMOUS_LOGIN_EXPIRED -> {
                        //游客态登录,但是token为空
                        //可以重新登录试下,需要控制频次 不要一直重复
                        KtvLoginService.anonymouslyLogin(this)
                    }
                    SDKLoginError.ANONYMOUS_LOGIN_FAIL -> {
                        //游客态登录,调用服务端接口失败,碰到40002错误码且sdk重试失败
                        //可以重新登录试下,需要控制频次 不要一直重复
                        KtvLoginService.anonymouslyLogin(this)
                    }
                    SDKLoginError.CANCEL -> {
                        //CANCEL事件(登录被取消),一般忽略即可

                    }
                    else -> {
                        Toast.makeText(
                            HostApp.getApp,
                            "登录失败: 错误码:$code ,错误信息: $msg",
                            Toast.LENGTH_SHORT
                        ).show()
                    }
                }
                return
            }
            else -> {

            }
        }
    }
    
    //登录前清除旧token
    //KtvLoginService.clearAccessToken()
    //调用登录
    //KtvLoginService.hiddenAccountLogin()

6.2 游客态登录(可选)#

以下接口在KtvLoginService类中。
void anonymouslyLogin(loginAPI: IKLoginAPI) - 游客态帐号登录;loginAPI:登录事件回调
允许接入方在未登录帐号时,调用接口进行游客态登录,登录后可以K歌;但此时是没有真实的K歌帐号,不能获取用户信息,会员状态等,也不能购买会员,只能用于试唱场景。
除非真有需要,否则只需要实现暗账号登录即可。游客态登录不是必须的。
登录成功回调LoginToken(val refreshToken: String, val openId: String, var overTimeMs: Long = 0L)
其中refreshToken为空,不允许刷新token,token过期需要重新登录;
错误处理与6.1.1小节一致。
对于游客态登录切换为暗帐号登录,需要先调用loginOut退出登录,再调用暗帐号登录的接口。
其他:
1.
对于暗帐号接入的厂商,为了进一步提高安全性,不需要在客户端提供appkey,即初始化sdk时传入的hostInfo中appKey应该为null或者空。
2.
demo中没有暗账号登录示例,只有扫码登录示例,如果要看demo体验下功能,可找孙康开通扫码登录权限。
修改于 2025-09-02 08:17:26
上一页
暗账号绑定明账号对接文档
下一页
获取应用级token
Built with