钉钉开发笔记(四)-签名验证问题的处理

摘要:
指甲开发中有PC和移动设备,这一点已经提到。最基本和最重要的部分是签名验证。只有在该步骤成功之后,才能调用JSAPI文档中某些组件的接口。钉钉服务器将用户发送的消息或用户触发的事件推送到企业应用程序进行处理,以下称为回调模式。

忙了一天竟然在一个以前自认为,很基础的问题上卡顿了,为了防止以后出现类似错误,决定还是记录下来,顺便整理下思路!


钉钉开发中有PC和移动之分,这个已经讲过,其中最基础也是最重要的当属其中的签名验证了,也只有这个步骤成功了你才可以调取JSAPI文档中的一些组件的接口。(不用钉钉组件的童鞋可以无视我这句  -。-)

其中PC版的签名验证算法如图:

 1 JS-API权限签名算法
 2 
 3 如果开发者想使用钉钉容器开放的jsapi接口,需要经过以下流程:
 4 
 5 首先需要获取jsapi_ticket。
 6 然后在web页面加载到钉钉容器时,通过jsapi权限验证配置接口验证可用的jsapi。这个接口使用的参数signature,在下文中有详细的说明。
 7 1.获取jsapi_ticket
 8 
 9 jsapi_ticket,是开发者调用钉钉JS接口的临时授权码,其作用主要用于生成签名,这个签名在jsapi权限验证配置接口中使用。
10 
11 正常的情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket。
12 
13 获取jsapi_ticket,具体可以参考文档
14 
15 2.签名生成算法
16 
17 开发者在web页面使用钉钉容器提供的jsapi时,需要验证调用权限,并以参数signature标识合法性
18 
19 签名生成的规则:
20 
21 List keyArray = sort(noncestr,timestamp,jsapi_ticket,url);
22 
23 String str = assemble(keyArray);
24 
25 signature = sha1(str);
26 
27 参与签名的字段包括在上文中获取的jsapi_ticket,noncestr(随机字符串,自己随便填写即可),timestamp(当前时间戳,具体值为当前时间到1970年1月1号的秒数),url(当前网页的URL,不包含#及其后面部分)。例如:
28 
29 noncestr=Zn4zmLFKD0wzilzM
30 jsapi_ticket=mS5k98fdkdgDKxkXGEs8LORVREiweeWETE40P37wkidkfksDSKDJFD5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcKIDU8l
31 timestamp=1414588745
32 url=//open.dingtalk.com
33 步骤1. sort()含义为对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)
34 
35 步骤2. assemble()含义为根据步骤1中获的参数字段的顺序,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串
36 
37 步骤2. sha1()的含义为对在步骤2拼接好的字符串进行sha1加密。

移动客户端签名验证如下:

 1 1.获取jsapi_ticket
 2 
 3 jsapi_ticket,是开发者调用钉钉JS接口的临时授权码,其作用主要用于生成签名,这个签名在jsapi权限验证配置接口中使用。
 4 
 5 正常的情况下,jsapi_ticket的有效期为7200秒,通过access_token(注意,假如您是ISV开发者,这个access_token需要企业授权的access_token接口)来获取。由于频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket。
 6 获取jsapi_ticket,具体可以参考文档)
 7 
 8 2.签名生成算法
 9 
10 开发者在web页面使用钉钉容器提供的jsapi时,需要验证调用权限,并以参数signature标识合法性
11 
12 签名生成的规则:
13 
14 List keyArray = sort(noncestr,timestamp,jsapi_ticket,url);
15 
16 String str = assemble(keyArray);
17 
18 signature = sha1(str);
19 
20 参与签名的字段包括在上文中获取的jsapi_ticket,noncestr(随机字符串,自己随便填写即可),timestamp(当前时间戳,具体值为当前时间到1970年1月1号的秒数),url(当前网页的URL,不包含#及其后面部分,需要对url中query部分做一次urldecode)。例如:
21 
22 noncestr=Zn4zmLFKD0wzilzM
23 jsapi_ticket=mS5k98fdkdgDKxkXGEs8LORVREiweeWETE40P37wkidkfksDSKDJFD5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcKIDU8l
24 timestamp=1414588745
25 url=//open.dingtalk.com
26 注意:必须要对生成签名的url的query部分做一次urldecode。例如,如果你的url是http://abc.com?url=http%3A%2F%2Fabc.com%2somewhere,那么你在生成签名的时候用到的url应该是对原url做过decode的url,即http://abc.com?url=http://abc.com/somewhere。否则可能会导致签名和服务端对应不上。
27 
28 步骤1. sort()含义为对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)
29 
30 步骤2. assemble()含义为根据步骤1中获的参数字段的顺序,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串
31 
32 步骤2. sha1()的含义为对在步骤2拼接好的字符串进行sha1加密。

其实仔细看来你就会发现,他们的唯一不同的地方就在于:移动端有url的编码,另外我可以告诉你,有没有编码的这一部分取决于你的url中是否存在中文字符,那么问题来了,是不是说移动和PC端的应用开发可以用同一套的签名呢?

答案是肯定的,而且是必须的!

为什么呢?

因为,在你获取accessToken的时候,你会发现他需要传入的参数只有corpId与CorpSecret,而且这两个入参是死值,也就是说,一个企业到的accessToken只有一个,而一个accessToken对应一个js_tiket,而且他们是存在时效和调取限制的yo!

 1 建立连接
 2 
 3 更新时间:2016/07/15 访问次数:31492
 4 主动调用
 5 主动调用的频率限制
 6 获取AccessToken
 7 获取微应用后台管理免登SsoToken
 8 你可以使用以下两种方式,将钉钉微应用连接到你的企业应用:
 9 
10 企业应用服务器调用钉钉开放平台提供的接口,以钉钉微应用的身份给企业用户的钉钉账号推送消息,以下称 主动调用模式。
11 
12 钉钉用户在使用企业提供的微应用H5页面时,该页面可以调用钉钉提供的JS接口,使用钉钉开放的终端能力和业务能力,以下称 JSAPI模式。
13 
14 钉钉服务器把用户发送的消息或用户触发的事件推送给企业应用,由企业应用处理,以下称 回调模式。
15 
16 主动调用
17 
18 当企业应用服务器调用钉钉开放平台接口时,需使用https协议、Json数据格式、UTF8编码,访问域名为 https://oapi.dingtalk.com。
19 在每次主动调用钉钉开放平台接口时需要带上AccessToken参数。AccessToken参数由CorpID和CorpSecret换取。对于ISV来说,获取企业授权的access_token
20 
21 CorpID是企业在钉钉中的标识,每个企业拥有一个唯一的CorpID;
22 
23 CorpSecret是企业每个应用的凭证密钥。
24 
25 CorpID及CorpSecret可以在钉钉为企业提供的管理后台中找到,由钉钉自动分配。
26 
27 POST请求请在HTTP Header中设置 Content-Type:application/json,否则接口调用失败
28 主动调用的频率限制
29 
30 当你获取到AccessToken时,你的微应用后台就可以成功调用钉钉后台所提供的各种接口或访问相应企业的资源或给成员发消息。
31 
32 为了防止微应用的程序错误而引发钉钉服务器负载异常,默认情况下,每个服务端调用接口都有一定的频率限制,当超过此限制时,调用对应接口会收到相应错误码。
33 
34 以下是当前默认的频率限制,钉钉后台可能会根据运营情况调整此阈值:
35 
36 每个企业调用单个接口的频率不可超过1500次/分
37 
38 每个ISV(应用提供商)调用单个接口的频率不可超过2000次/分
39 
40 每个ISV(应用提供商)调用单个企业的单个接口频率不可超过1500次/分
41 
42 每个套件调用单个企业的单个接口频率不可超过1000次/分
43 
44 获取AccessToken
45 
46 AccessToken是企业访问钉钉开放平台接口的全局唯一票据,调用接口时需携带AccessToken。
47 
48 AccessToken需要用CorpID和CorpSecret来换取,不同的CorpSecret会返回不同的AccessToken。正常情况下AccessToken有效期为7200秒,有效期内重复获取返回相同结果,并自动续期。

所以一般都会存在缓存策略,但是缓存策略的话会存在一个问题,那就是tiket的时效性问题!

即,一般公司存在多个项目时,大多会开发多个独立的数据库项目与之对应。往往会在其每个数据库中独自调用一种配置方法,但是这也是问题所在!所以我推荐大家采用多个项目调用一种配置的方法。这样就不会存在tiket时效从而签名验证失败的问题了!

免责声明:文章转载自《钉钉开发笔记(四)-签名验证问题的处理》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇使用NPOI读取Excel表格内容并进行修改python3.8+PySimpleGUI+进度条代码大全下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

接口测试常见bug

一、接口参数数据类型:1. 数值型2. 字符串类型3. 数组或者 链表类型4. 结构体二、接口测试常见bug:1. 特殊值处理不当导致程序异常退出或者崩溃2. 类型边界溢出,导致数据读出和写入不一致3. 取值边界外值未返回正确的错误信息4. 参数 为null或空字符串“”等5. 权限未处理,可以访问其他用户的信息例如:无权限可以访问,或者 一般用户可以访问...

mybatis 详解(六)------通过mapper接口加载映射文件

通过 mapper 接口加载映射文件,这对于后面 ssm三大框架 的整合是非常重要的。那么什么是通过 mapper 接口加载映射文件呢?   我们首先看以前的做法,在全局配置文件 mybatis-configuration.xml 通过 <mappers> 标签来加载映射文件,那么如果我们项目足够大,有很多映射文件呢,难道我们每一个映射文件都这...

接口测试-自动化-Java-思路

这次模拟学习的思路是这样的: 目的: 为了能测试接口是否运行正常, 因为公司目前人员流动比较大,之前的后台接口开发人员已经离职,目前线上接口已经运行, 再出现新需求的情况下,如果没有开发新的接口,不确定是否会因为同步代码等其他问题造成接口不可用。 如果没有太多的时间测试每个接口是否正常,可以使用自动化脚本进行测试,保证每个接口运行正常。 注:当然接口测试还...

从手机浏览器或者 APP 中跳转到微信并跳转到指定页原理及行业内幕详解

相信很多朋友遇到过有些网站,可以直接通过一个连接就能让你的手机打开微信且跳转到某个指定的页面,许多程序员很好奇到底是怎么实现的,到处求这种方法的源码,在文本中我会介绍及剖析这种跳转实现的原理。     微信是个比较封闭的环境,至于为什么封闭,相信大家都了解,在一些应用场景中,我们要用到外部浏览器跳转到微信内部打开,比如添加好友、微信支付等,在微信内部环境...

Java 基础 AutoCloseable &amp;amp; Closeable

Overview Closeable和AutoCloseable都是接口,且都只定义了一个close()方法。Closeable: 定义于 java.io包中,于JDK5添加;AutoCloseable: 定义于java.lang包中, 于JDK7添加; AutoCloseable.java public interface AutoCloseable{...

python调用接口,python接收post请求接口(附完整代码)

  与Scala语言相比,Python有其独特的优势和广泛的应用,python调用接口,因此Spark也推出了PySpark,它在框架上提供了一个使用Python语言的接口,python接收post请求接口为数据科学家使用框架提供了方便。  众所周知,Spark框架主要由Scala语言实现,它还包含少量的Java代码。Spark面向用户的编程接口也是Sca...