Tplogin用户登录及授权接口(JSON)

                                                                                                                                                                                   

概述

手机银行开放了用户登录和认证接口,通过该接口可以进行客户核身,并获取部分客户信息。根据商户类型的不同,返回不同的权限内容。文档已经迁移到新网站,此文档不再更新和维护,请移步 Tplogin(Json)登录授权接口-通用


名词解释

1.1商户

对第三方应用的统称,包括分行应用、外部合作公司应用、非手机银行平台的内部应用。


1.2联合登录

招商银行APP登录后将令牌发送给第三方应用,第三方应用通过解析令牌即可获得用户相关信息,这一过程称为联合登录。联合登录将手机银行用户体系开放给第三方,使得在第三方应用中无需执行登录即可获得用户信息。


1.3授权

第三方应用想要通过联合登录获取用户信息需要经过手机银行侧授权:即先要在线下通过商户管理员申请商户号、密钥等信息,并在线上发起联合登录请求时通过参数带入的方式传入商户号等信息,手机银行校验通过后方才将令牌发送给第三方应用。


1.4令牌

手机银行登录成功后将用户信息加密并签名后通过Http请求(POST方式)发送给第三方应用,加密后的用户信息称为令牌。


1.5签名与验签

手机银行发送给第三方应用的加密数据中包含了一段签名数据,它经过手机银行私钥加密产生,第三方应用需在拿到密文数据并解密后,对签名数据进行验签,即使用手机银行公钥匹配验证,防止数据被篡改。详见“安全控制”章节。


交互流程

参数说明

3.1传入参数

第三方应用前端js通过调用tplogin接口唤起手机银行APP登录,请求示例如(以华彩证券为例):location.href=”tplogins://www.huacai.cn/iphone_buy.do?param=xxxxx&corpno=123123&auth=6c1c600b27347c220a076b41c064ca6b”,可将此段js代码置于页面加载事件中。

参数名

参数释义

备注

tplogin(s)

唤起登录指令,若商户回调url使用http协议则为tplogin,若商户回调url使用https协议则为tplogins


param

param 商户希望招商银行侧透传的参数(需要进行urlencode处理),可有可无


corpno

corpno 商户号,由招商银行侧分配


auth

授权信息,商户侧对请求内容与corpkey拼接后进行MD5得到的字符串


corpkey

商户密钥(原KEY),由招商银行侧分配



登录唤起示例代码,Jquery为例:

$(document).ready(function(){
location.href=”tplogins://www.huacai.cn/iphone_buy.do?param=xxxxx&corpno=123123&auth=6c1c600b27347c220a076b41c064ca6b”;
});

auth计算示例伪代码(注意:tplogins链接需全部小写,包括corpkey):

auth=MD5(strtolower(tplogins://www.huacai.cn/iphone_buy.do?param=xxx&corpno=123123+corpkey)));//+号仅代表连接符,实际代码中无此符号

3.2传出参数

手机银行完成登录后通过发起回调url请求(POST方式),将加密后的用户授权信息发送至第三方应用,如:https://cmbchina.huacai.cn/iphone_buy.do?param=xxxxx]


参数名

参数释义

备注

param

如上,商户希望招商银行侧透传的参数,GET方式


sResponseXml

通过POST方式返回应答报文,json格式,如:

{

"resultType":"Y",

"cryptType":"2",

"body":"/qigtuR2GX2aR5z+z329BCDH8q7cpRdOe9fMJBW7Emob9="

}

a. resultType即登录结果:Y表示成功,N表示失败,成功时body中放置加密密文,失败时放置失败原因(明文);

b. cryptTypebody加密类型:1表示明文,2表示DES加密,3表示非对称加密;

sResponseXml中的body内容

用户授权信息,以密文形式展示,第三方应用需先Base64解码并进行DES解密后方能看到明文数据。

用户信息均以json格式返回,不同商户拿到的信息会有不同。


第三方应用在进行DES解密用户授权信息时,关于DES算法一些参数指定如下:

●密钥:即corpkey(开发联调环境统一使用“cmbtest1”,生产环境需上线前申请);

●解密模式:ECB

●填充模式:PKCS5Padding(Java)/PKCS7Padding(C#)

●编码字符集:UTF-8


当解密完成时,第三方应用会看到如下json格式的用户明文数据,具体信息视第三方应用需求场景而分配,详细信息字段名及释义见附录1

--------------------------------------------------------------------------------------------------------------------------------

{

"type":"2",

"data":{

"corpInfo":{

"newUserID":"UI3QQS3D+YnE8+l+SvHUZd6q260sU=",

"uniqueUserID":"UQk0qwg8H0ynDQ/KrC+47SScXyV98=",

"expandUserID":"EUgxFOg1xey1BA8j99r2uEx3GlSvY="

},

"customerInfo":{

}

},

"verify":"143|198|70|189|146|178|225|103|193|37|38|18|38|224|193|5|8|104|29|236|170|233|165|198|219|225|201|144|59|115|233|198|46|21|10|231|52|145|238|246|214|115|143|126|81|11|182|197|91|243|236|153|167|23|242|218|249|18|125|77|136|71|237|174|"

}

--------------------------------------------------------------------------------------------------------------------------------


DES解密示例伪代码:

--------------------------------------------------------------------------------------------------------------------------------

//密文数据Base64转码

userdata = base64decoder.decode(UserDataBase64);

//获取密钥byte数组

key = corpkey.getbyte(“UTF-8”);

//设置des解密模式

desdecrypter.mode = ECB;

//设置des填充模式(JavaPKCS5.NETPKCS7

desdecrypter.padding = PKCS5;

//des解密得到明文数据

decryptdata =desdecrypter.decrypt(userdata, key);

--------------------------------------------------------------------------------------------------------------------------------



安全控制

招商银行保证提供给第三方的授权令牌信息是合法有效的,但第三方必须采取以下措施,以避免开放环境下的信息安全风险。

4.1加解密

户信息采用DES对称加密,密钥由手机银行签发,(联调测试环境统一用“cmbtest1,生产环境需上线前申请),第三方应用应妥善保管,避免泄露;第三方应用应禁止在前端解密用户信息,严禁以明文方式在前端展示或缓存用户敏感信息,在解密得到用户信息后必须以安全方式传输。


4.2签名验证

手机银行签发的令牌附有数字签名,为确保授权信息的合法有效性,第三方应用必须调用招商银行提供的验签API(jardll)以及公钥来验证签名。具体做法是,将用户信息中的body解密后中的dataverify拼接,格式为“data&signature=verify内容”,把拼接内容与公钥一起传入验签API进行验证,得到验签结果。需要特别注意的是需先对data内容进行Base64转码后,再拼接进行验签。相关接口及公钥参见附录2“手机银行登录授权API验签工具包.zip”。


另外,令牌中包含有时间戳,第三方应用应验证令牌时间戳,控制到一个合理范围(一般10-30分钟),如超出则当前令牌失效,提示用户重新登录。


签名验证调用示例源代码(注意,此处为验签调用方式为可复用的源代码):

----------------------------------------------------------------------------------------------------------------------------

//首先保证已导入验签APIJava已导入jar包,C#已导入dll(将dll拷至bin目录)

//参数说明:

//signdata为拼接内容即signdata=strBody(Base64转码后)+&signature=+strVerify;

//publickeypath为公钥存放的物理路径

//---------Java调用验签示例(需引入命名空间cmb.netpayment.* ------------

import cmb.netpayment.*;

public static booleanVerifySignature(signdata, publickeypath){

Security verifier = new Security(publickeypath);

return verifyer.checkInfoFromBank(signdata.getBytes(Encoder.UTF_8));//成功时返回true

}

//---------C#调用验签示例(需在验签方法前声明外部函数)------------

[DllImport("FirmClient.dll",CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]

public static extern intCheckInfoFromBank(string sPublicPath, string sBody);

public static int VerifySignature(signdata,publickeypath){

return CheckInfoFromBank(publickeypath,signdata);//成功时返回0

}

--------------------------------------------------------------------------------------------------------------------------------


用户授权申请

招商银行APP版本7.3.0及以上,针对要获取敏感信息的外部商户将增加用户授权申请环节,行内商户无需处理。

5.1 用户授权申请页面

(备注:授权申请页中间的权限描述根据商户权限不同而不同)


5.2 用户授权申请点击

以外部商户获取手机号为例(手机号为敏感数据):

1)用户A,第一次触发tplogin

①用户点击“同意”

令牌包含敏感数据,即包含手机号。

②用户点击“拒绝”

令牌不包含敏感数据,即不包含手机号,并且在令牌解密后的明文中新增字段userAttitude”:”0”

2)用户A,第nn>1)次触发tplogin

不再出现授权申请页面,沿用第一次用户A的选择,即第一次选择“同意”,之后tplogin请求获取的令牌均包含敏感数据;第一次选择“拒绝”,之后tplogin请求获取的令牌均不包含敏感数据。


5.3 商户再次向用户申请授权

若是商户需要再次向用户A申请授权,需在tplogin请求中携带参数snt=Y,如:

tplogins://www.huacai.cn/iphone_buy.do?param=xxxxx&corpno=123123&auth=6c1c600b27347c220a076b41c064ca6b&snt=Y

将再次出现授权申请页面。


测试客户端下载、申请测试环境小程序商户号

测试说明

分行(或合作商户)在开发和测试阶段,若需要进行接口的联调和测试,可通过测试客户端连接到我行的测试环境。请按以下步骤进行(各个步骤的详细内容在下文中将有详述):

1、申请测试环境的商户号、申请配置测试入口;

2、安装测试客户端,并连接所需的环境;

3、在测试客户端内找到测试入口,进行联调和测试;

申请测试商户号/测试入口

发邮件给ben_chan@cmbchina.com,抄送给lilizao@cmbchina.com

邮件需要提供以下信息:

商户类型(行内/行外)

测试用的小程序URL地址

小程序名称

页面顶部是否需要使用手机银行默认的导航栏(是/否)

该小程序是否需要使用一网通支付(是/否)

需要在邮件中提及JSON报文格式

我行人员完成配置后,会回复邮件,邮件包含:测试安装包下载地址、测试商户号、测试入口在测试客户端内的位置、测试秘钥;

测试环境说明

打开测试客户端,会弹框提示选择需要连接的测试环境,请根据自己的实际情况进行选择;

行外使用(DMZ

121.15.180.72,端口号:80

行内使用

99.12.73.80,端口号:888(不需要使用一网通支付)

99.12.69.80,端口号:80802(需要用到一网通支付)

测试商户号/密钥

测试商户号以邮件反馈的为准,测试秘钥统一使用cmbtest1

测试用一网通账号/银行卡号

银行卡号:6225886551249897,登录密码:774411

一网通账户(登录密码均为774411

18943444960

13840831542

15835605832

一网通非实名账户

17577441100(密码:77441100

测试安装包下载地址

测试安装包下载请点击这里

测试客户端使用方法

安装后,会弹框提示,请选择需要连接的环境(请确认host和端口号与申请的是否一致)



申请正式环境小程序商户号申请

在小程序正式上线前,需要提前向总行申请生产环境正式的商户号和秘钥等配置信息。从手机银行7.0版本开始,小程序可以纳入手机银行APP首页的十宫格推荐算法,希望纳入推荐算法的小程序,需要单独申请一个商户号,不可与其他小程序共用。关于商户号共用的问题,具体请看这里:多个小程序可否共用一个商户号和秘钥?

由于手机银行侧配置发布采取灰度策略,每个版本发布需要经历约一周时间,因此请在自身应用上线前(或营销推广前)至少提前2周向总行发起参数上线申请,如果上线时间紧迫,可以无需等到应用开发完成,提前申请商户号和秘钥。

申请方式为:由分行的业务部门或分行信息技术部的相关同事(如果是外部商户,须由商户拓展分行发送邮件)发邮件给招商银行小程序管理/80266529(邮箱:xiaochengxu@cmbchina.com),并抄送给发件人的主管和李立早/01149824、郑璇/224899,邮件标题为:xx分行申请小程序商户号和秘钥,并在邮件内填写如下表格,表格内有填表说明;小程序商户号申请表(模板&填表说明)_20181218.xls邮件中需要注明申请报文格式为json版本。

注:如对上表有疑问可直接咨询总行李立早/01149824


附录1.内部商户授权信息字典

参数名

参数释义

备注

卡列表信息(cardNoList节点内容)

CardNoType

账户类型

01:本行借记卡

02:本行信用卡

11:他行借记卡

12:他行信用卡

99:一网通账户

cardNo

卡号(一卡通)或账户号(信用卡)


customerID

核心客户号


mobileNo

手机号码


defaultCardFlag

默认卡标识


bankName

所属银行

如:招商银行

acctBranch

一级分行号

如:0755

accountLevel

账户等级(I类户、II类户等)

V0:I类户(掌上生活开户的电子一卡通)  V1:I类户 V2:II类户 V3:III类户 F0:一卡通附属卡空:未知/信用卡

商户信息(corpInfo节点内容)

corpName

商户名称


corpNo

商户号


appName

APP名称


appVersion

APP版本号


newUserID

用户ID,由身份证+姓名+商户号生成

逐渐废弃,不建议使用

uniqueUserID

用户ID,由身份证+姓名生成

推荐使用

expandUserID

用户ID,由一网通ID生成

ExpandUserID为非实名用户的唯一ID,当UniqueUserIDNewUserID均为空时,该用户为非实名用户

timeStamp

时间戳

24小时制

客户信息(customInfo节点内容)

realName

客户姓名


idType

证件类型

01-身份证,02-护照,03-其他

personalID

证件号码


mobile2

银行预留手机号

优先取值为一卡通预留手机号,若取不到,则根据登录类型获取,即信用卡登录为信用卡预留手机号,一网通登录为一网通注册手机号

level

客户等级

客户所持卡中的最高卡等级

LV1-普卡、LV2-金卡、LV3-金葵花、LV4-砖石卡、LV5-私人银行

登录信息(loginInfo节点内容)

loginType

登录类型

A-一卡通,C-信用卡,D-一网通

loginID

登录ID

A-一卡通卡号,C-身份证号,D-一网通用户号

netBankUserName

一网通登录名


appID

设备ID


version

客户端版本


clientIP

客户端IP


netBankMobile

一网通预留手机号


netBankEMail

一网通注册邮箱


netBankLoginName

一网通注册自定义用户名


备注:加粗部分为20181120后新增的字段,原有内部商户需要时请向李立早报备,新的内部商户均开放。


附录2.外部商户授权信息字典

参数名

参数释义

备注

newUserID

用户ID,由身份证+姓名+商户号生成

逐渐废弃,不建议使用

uniqueUserID

用户ID,由身份证+姓名生成

推荐使用

expandUserID

用户ID,由一网通ID生成

ExpandUserID为非实名用户的唯一ID,当UniqueUserIDNewUserID均为空时,该用户为非实名用户



附录3.支持小组

1、总行业务联系人:李立早/01149824

2、测试环境技术支持:陈伟锋/80274221

3、疑难问题技术支持:张星/80230395

4、手机银行登录授权API验签工具包下载:手机银行登录授权API验签工具包


FAQ

Q1:第三方商户地址未能通过校验,可能不是合法地址。

A1:发起tplogintplogins请求时,参数auth值计算错误。请检查商户秘钥是否正确,计算authmd5算法及输入参数是否正确。

Q2:跳转失败![无效的商户号-A002]

A2:服务端无此商户的配置,测试环境联系陈伟锋,生产环境需联系总行李立早提前2周申请。

Q3Android:登录失败,请重新登录再试!(服务端正在更新,请稍后再试)

A3:服务端商户配置存在错误,可能是商户号被重复使用,测试环境请联系陈伟锋。

Q4Android点击取消登录又唤起一次登录。

A4:请通过前端发起tplogins请求,使用window.location.href= tplogins://…”;

Q5DES解密失败。

A5:(1)检查获取到的SresponseXml是否+号被转义成空格了,请将空格替换回加号;


Q6:数字验证签名失败。

A6:待验证参数 = “原文&signature=签名
原文:DES解密结果中data的内容(需要将data内容转成json字符串,注意datajson字符串中字段的顺序,需要和des解密后的data字符串顺序一致,并且进行base64转码);
签名:DES解密结果中verify的内容。
例如原文为“this is a test”,签名为“123|456|789|”,那么参数就是“this is a test&signature=123|456|789|”


注:如果使用的是alibabafastsjon,需要使用JSONObject reqJSON = JSONObject.parseObject(body,Feature.OrderedField);

(1)C#签名验证失败

返回值

描述

0

验签成功

13

public.key文件的路径错误

14

待验证的数据拼接不正确


(2)Java签名验证失败

返回值

描述

true

验签成功

false

验签失败(public.key路径不正确,验签内容不正确)



Q7:内部商户测试数据

{

"resultType":"Y",

"cryptType":"2",

"body":"u9su4Mi92g8b2l1GjBEllZQBpjFxRbKYY4MNjgS7qyS4GajzsQbyHPC6Xon2lc+gPjF3kjQalI2WNWw3UpY6M3RU4B6GFEC6IWf6KxYtcF4D9BJ6SrnW+LG1ncaArA8yJaAnlF42uMP4pHnWfJcIwBlobdjBJtCM/jgyvqSDq8EbGuUbEzfTBdWNGul6Zfr4MfvQFNE/KcsETGb6HrXayCR+ZD7aQ6dfk4wdd47Lpw14apcdMK8S3YaoOWN5NTgFgvqN8CyoZWJWFtZvntMozOWfKcgSIC5iTnVQsDYtnyvoPXvLMQRK2RngCMfHNyj8KHmtqLvapwCimVrD34/vV3n4WmQ4d+yPpMthMwg9NH6dxuC92tmfmeSNnfB3Ru3sZyo5PlxCrAyEaP7V2nnMg+JC9KuBf43TcrvQFAMJ9/YzjnYQLw4uVH58q0ebCcCY5Wvoda74aMRM+uWYY8RTFclmCyyyCEcttY1XzDS+zOCDu6rhjiDswDXno+YWbgU3G2skHRoMMxjOGmCUS1u6rrHp+6ERZa/YiRH77PFcilAsIbINkmBKgm8r/qe3m81nO8u2U6pEHp4="

}

上述标红部分(body内容)即用户授权信息,先经Base64解码后DES解密,若解密成功显示json结果如下,若解密失败首先考虑返回报文中“+”号被转义成了空格。

{

"type":"2",

"data":{

"corpInfo":{

"newUserID":"UI3QQS3D+YnE8+l+SvHUZd6q260sU=",

"uniqueUserID":"UQk0qwg8H0ynDQ/KrC+47SScXyV98=",

"expandUserID":"EUgxFOg1xey1BA8j99r2uEx3GlSvY="

},

"customerInfo":{

}

},

"verify":"143|198|70|189|146|178|225|103|193|37|38|18|38|224|193|5|8|104|29|236|170|233|165|198|219|225|201|144|59|115|233|198|46|21|10|231|52|145|238|246|214|115|143|126|81|11|182|197|91|243|236|153|167|23|242|218|249|18|125|77|136|71|237|174|"

}


data内容转base64后的结果为:

"eyJjb3JwSW5mbyI6eyJuZXdVc2VySUQiOiJVSTNRUVMzRCtZbkU4K2wrU3ZIVVpkNnEyNjBzVT0iLCJ1bmlxdWVVc2VySUQiOiJVUWswcXdnOEgweW5EUS9LckMrNDdTU2NYeVY5OD0iLCJleHBhbmRVc2VySUQiOiJFVWd4Rk9nMXhleTFCQThqOTlyMnVFeDNHbFN2WT0ifSwiY3VzdG9tZXJJbmZvIjp7fX0="

Q8:报错排查。

A10

编号

报错信息

报错原因

No.1

[301]您的一网通用户需要先进行实名认证才能继续操作。

该一网通用户未实名,可通过绑卡实名

No.2

对不起,此功能正在维护中,暂停使用#I1

服务端配置有误,测试环境请联系陈伟锋处理,生产环境请联系支持小组。

No.3

对不起,此功能正在维护中,暂停使用#I2

服务端系统异常,测试环境请联系陈伟锋处理,生产环境请联系支持小组。

No.4

对不起,此功能正在维护中,暂停使用#I3

No.5

对不起,此功能正在维护中,暂停使用#I4

No.6

对不起,此功能正在维护中,暂停使用#I5

No.7

对不起,此功能正在维护中,暂停使用#IR

No.8

抱歉,系统正在维护#2......

No.9

系统正在维护中#1






Q9:多个小程序可否共用一个商户号和秘钥?

A9:每个小程序必须申请独立的商户号和秘钥,做到“一号一用”。多个小程序混用同一个商户号会导致数据统计不准确、无法使用短链接、无法通过算法推荐出现在首页宫格等问题。


Q10:调用了用户授权及登录接口,但是没有相关信息返回?

A10:网络问题,请参考http://99.12.136.169/index.php?s=/20&page_id=203中的“2.商户/小程序页面打不开”。


Q11:提示“商户跳转失败,商户号不能为空”?

A11:小程序发起请求时未传商户号。


Q12ST环境可以登录验签成功,UAT环境不行?

A12:数字签名验证方法未覆盖所有场景,测试账号不同,授权数据也就不同,用于验签的body内容也会不同。


Q13:手机银行已登录状态可以进入测试页面,未登录进入测试入口报405错误?

A13:登录授权接口要求小程序应用允许getpost两种请求,针对分行小程序应用部署在paas上的nginx容器里,其解决方案:在nginx.conf配置error_page 405 = $urierror_page 405 = 200 $uri


Q14:验签API中,Java导入的jar包如何引用?

A14:没放maven,采用本地引用方式。