钉钉二次开发分为如下表所示三种类型的开发,只有企业内部应用才需要对JSAPI鉴权。

类型

开发方式

JSAPI鉴权

应用场景

第三方企业应用

E应用开发

不需要

用于发布到钉钉应用市场,供广大用户下载,应用可选收费或免费,需要收取保证金,并进行应用审核

企业内部应用

H5开发,8月中旬也开始支持E应用开发

需要

只能企业内部应用,不能发布到钉钉市场

第三方个人应用

E应用开发

需要

应用与企业不挂钩,服务于个人

先来看一下钉钉官网给出的JSAPI鉴权的流程,它分为四个步骤:

  1. 获取token
  2. 获取ticket
  3. 获取数字签名
  4. 设置权限

查看钉钉开发文档,它给出了两个JSAPI的鉴权demo,分别是java和php的,需要前后端配合,而本文讲述的是纯前端JSAPI鉴权,完全实现前后端分离。

下面的代码将用到以下三个js依赖包:

import CryptoJS from 'crypto-js'; // 加密,用于生成数字签名
import * as dd from "dingtalk-jsapi"; // 钉钉JSAPI
import axios from "axios"; // HTTP请求

提示:下面的代码,用了ES6和ES7的一些语法,没接触过的朋友,可自行百度

1、获取token

首先根据corpid和corpsecret参数,从钉钉服务器获取token。

/**
* 获取token信息
* @param {Object} params {corpid, corpsecret}
*/
async function getToken(params) {
return await axios.get('/proxy/gettoken', {
params
})
.then(function(response) {
return response.data.access_token;
});
}

细心的朋友会发现,axios请求的URL并没有直接指定 https://oapi.dingtalk.com/gettoken,这是因为直接写这个URL,会存在跨域问题,因此,这里我们用了代理。

代理可以采用nginx代理或者node代理,这里推荐用node代理。

因为需要代理的请求是https请求,本人也没跑通nginx代理https请求,如果有哪位朋友跑通了nginx代理的,麻烦告知一声,也学习以下。

2、设置代理

如果采用vue-cli创建的项目,可以直接在proxyTable中配置,如下:

 proxyTable: {
'/proxy': {
target: 'https://oapi.dingtalk.com',
secure: false,
// 设置跨域
changeOrigin: true,
pathRewrite: {
'^/proxy': ''
} }
}

不过上面的配置只能在dev开发环境中使用,如果需要在生产环境中使用,还是需要自己写nodejs代码实现,如下:

var express = require('express');
var proxy = require('http-proxy-middleware'); var app = express(); app.use('/proxy', proxy({
target: 'https://oapi.dingtalk.com',
changeOrigin: true,
pathRewrite: {
'^/proxy': ''
}
}));
app.listen(3000);

这代码量是不是很少,随便百度下都搞定。

3、获取ticket

根据上面获取的access_token,从钉钉服务器获取ticket。

/**
* 获取ticket信息
* @param {Object} params {access_token}
*/
async function getJsticket(params) {
return await axios.get('/proxy/get_jsapi_ticket', {
params
})
.then(function(response) {
return response.data.ticket;
});
}

4、获取数字签名

钉钉官网的demo是后台实现生成数字签名,通过crypto-js前端加密库就可以将这个功能移植到前端来。

ticket是上面生成的;

nonce可以是任何字符串;

timeStamp是当前时间戳;

url是当前访问的URL地址,不包括#及后面的部分,特别注意这个参数,别搞错了。如果设置错了,可以通过下面的dd.error输出查看钉钉服务器获取的URL地址

/**
* 获取签名信息
* @param {*} ticket
* @param {*} nonce
* @param {*} timeStamp
* @param {*} url
*/
function getJsApiSingnature(ticket, nonce, timeStamp, url) {
let plainTex = "jsapi_ticket=" + ticket + "&noncestr=" + nonce + "&timestamp=" + timeStamp + "&url=" + url;
let signature = CryptoJS.SHA1(plainTex).toString();
return signature;
}

5、设置权限

通过dd.config设置需要的权限

// 步骤4:设置权限
dd.config({
agentId: agentId,
corpId: corpid, //必填,企业ID
timeStamp: timeStamp, // 必填,生成签名的时间戳
nonceStr: nonce, // 必填,生成签名的随机串
signature: signature, // 必填,签名
jsApiList: jsApiList // 必填,需要使用的jsapi列表,注意:不要带dd。
});

jsApiList是权限列表,如:

var jsApiList = [
'biz.user.get',
'device.geolocation.get',
'biz.util.uploadImage'
];

6、验证

上面配置成功之后,就能调用JSAPI中需要鉴权的功能了,下面以获取当前地理位置为例说明:

/**
* 测试代码,通过调用位置服务,测试鉴权是否正确
*/
function testJsApi() {
// 获取位置
dd.ready(() => {
dd.device.geolocation.get({
targetAccuracy: 200,
coordinate: 1,
withReGeocode: false,
useCache: true, //默认是true,如果需要频繁获取地理位置,请设置false,
onSuccess: result => {
/* 高德坐标 result 结构
{
longitude : Number,
latitude : Number,
accuracy : Number,
address : String,
province : String,
city : String,
district : String,
road : String,
netType : String,
operatorType : String,
errorMessage : String,
errorCode : Number,
isWifiEnabled : Boolean,
isGpsEnabled : Boolean,
isFromMock : Boolean,
provider : wifi|lbs|gps,
accuracy : Number,
isMobileEnabled : Boolean
}
*/
console.log(result)
alert("success: " + JSON.stringify(result))
},
onFail: err => {
console.log(err)
alert("error: " + JSON.stringify(err))
}
});
}); // 查看鉴权错误信息
dd.error(function(err) {
alert('dd error: ' + JSON.stringify(err));
});
}

如果鉴权失败,则dd.error将输出钉钉服务器采用的数字签名参数,可以与自己采用的参数做比较

附:串起来的代码

async function getAccessToken() {
// 步骤1:获取token
let access_token = await getToken({
corpid,
corpsecret
}); // 步骤2:获取ticket
let ticket = await getJsticket({
access_token
}); // 步骤3:获取数字签名
let signature = getJsApiSingnature(ticket, nonce, timeStamp, url); // 步骤4:设置权限
dd.config({
agentId: agentId,
corpId: corpid, //必填,企业ID
timeStamp: timeStamp, // 必填,生成签名的时间戳
nonceStr: nonce, // 必填,生成签名的随机串
signature: signature, // 必填,签名
jsApiList: jsApiList // 必填,需要使用的jsapi列表,注意:不要带dd。
}); // 测试定位功能
testJsApi();
}

钉钉JSAPI前端鉴权的更多相关文章

  1. vue之前端鉴权

    vue项目前端鉴权方式常用的有以下三种: 1.渲染菜单时控制模块按钮的显示隐藏(不足:直接输入链接仍然可以访问模块) 2.在路由导航守卫中拦截,针对没有权限的模块进行重定向(不足:每次访问模块都需要鉴 ...

  2. Tips_钉钉免登前端实现

    1.需求:开发钉钉微应用,需要实现钉钉的免登陆功能. #.其实钉钉的文档中心还是很详细的,只是刚开始接触会一头雾水,所以花费了挺多时间....... ?什么是钉钉免登功能. ?企业应用免登开发授权流程 ...

  3. 钉钉小程序不用canvas在后端绘图前端用image标签获取图片的实践

    公司的需求要用电子员工卡代替用了N久的工作证,在各种场合刷二维码来代替刷卡.在钉钉小程序里实现.感觉这回又要躺坑里了. 钉钉小程序第一次做.我这个自封的GDI+大神才不要想用钉钉jsapi的方式用ca ...

  4. 钉钉客户端JS-API权限签名算法.NET版

    前段时间写了一篇博文<钉钉如何进行PC端开发>,在里面并未解决本地生成签名的问题,需要到官网进行生成,由于钉钉门票等认证信息会超期,因此,必须能本地用代码自动更新相关参数信息,来换取签名. ...

  5. Java钉钉开发_02_免登授权(身份验证)(附源码)

    源码已上传GitHub: https://github.com/shirayner/DingTalk_Demo 一.本节要点 1.免登授权的流程 (1)签名校验 (2)获取code,并传到后台 (3) ...

  6. Java钉钉开发_03_通讯录管理之 人员管理 和 部门管理

    一.本节要点 1.通讯录权限 ISV(应用服务商)默认无管理通讯录的权限,企业应用默认有所有通讯录权限. 2.数据传输格式—JSON 请参见: Java_数据交换_fastJSON_01_用法入门 二 ...

  7. 钉钉开发入门,微应用识别用户身份,获取用户免登授权码code,获取用户userid,获取用户详细信息

    最近有个需求,在钉钉内,点击微应用,获取用户身份,根据获取到的用户身份去企业内部的用户中心做校验,校验通过,相关子系统直接登陆; 就是在获取这个用户身份的时候,网上的资料七零八落的,找的人烦躁的很,所 ...

  8. 钉钉微应用接入钉钉免登陆配置记录。NET实现

    在这里记录一下我配置的钉钉接入微应用遇到的坑.搞了我几天天才调通.头皮发麻,现在梳理一下,以免别人也入坑. 1.钉钉接入主要要获取钉钉企业员工的ID,然后去自己的应用的数据库里进行匹配然后实现免登陆的 ...

  9. Java钉钉开发_02_免登授权(身份验证)

    源码已上传GitHub: https://github.com/shirayner/DingTalk_Demo 一.本节要点 1.免登授权的流程 (1)签名校验 (2)获取code,并传到后台 (3) ...

随机推荐

  1. harbor在谷歌云上搭建 日志

    参考:https://github.com/vmware/harbor/blob/master/docs/installation_guide.md 日志: [root@instance-1 harb ...

  2. [Swift]LeetCode324. 摆动排序 II | Wiggle Sort II

    Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]... ...

  3. java中this和super关键字的使用

    这几天看到类在继承时会用到this和super,这里就做了一点总结,与各位共同交流,有错误请各位指正~ this this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针. this ...

  4. SecureCRT 5.2.2版本下载和注册码

    Name: Apollo Interactive Company: Apollo Interactive Serial Number: 03-50-023223License Key: ABMVSR ...

  5. Spring Boot @ControllerAdvice 处理全局异常,返回固定格式Json

    需求 在构建RestFul的今天,我们一般会限定好返回数据的格式比如: { "code": 0,  "data": {},  "msg": ...

  6. Zara带你快速入门WPF(2)---布局篇

    一.章节目标 这几章节我们会创建一个完整的Window程序,包括使用DataGrid空间,数据绑定是把.NET类中的数据提供给用户界面的一个重要概念,还允许修改数据,包括.NET4.5新增的INoti ...

  7. asp.net core系列 27 EF模型配置(索引,备用键,继承)

    一.索引 索引是许多数据存储中的常见概念.虽然它们在数据存储中的实现可能会有所不同,但它们可用于更有效地基于列(或列集)进行查找.按照约定,用作外键每个属性 (或组的属性) 会自动创建索引.无法使用数 ...

  8. SpringBoot入门教程(十)应用监控Actuator

    Actuator可能大家非常熟悉,它是springboot提供对应用自身监控,以及对应用系统配置查看等功能.spring-boot-starter-actuator模块的实现对于实施微服务的中小团队来 ...

  9. Java基础17:Java IO流总结

    更多内容请关注微信公众号[Java技术江湖] 这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM.SpringBoot.MySQL.分布式.中间件.集群.Linux ...

  10. ARP欺骗攻击

    一.ARP攻击概述 ARP攻击主要是存在于局域网中,通过伪造IP地址和MAC地址实现ARP欺骗,能够在网络中产生大量的ARP通信量使网络阻塞,攻击者只要持续不断的发出伪造的ARP响应包就能更改目标主机 ...