继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

钉钉JSAPI前端鉴权

慕丝7291255
关注TA
已关注
手记 94
粉丝 15
获赞 69

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

类型

开发方式

JSAPI鉴权

应用场景

第三方企业应用

E应用开发

不需要

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

企业内部应用

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

需要

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

第三方个人应用

E应用开发

需要

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

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

  1. 获取token

  2. 获取ticket

  3. 获取数字签名

  4. 设置权限

https://img.mukewang.com/5b8bab5300011e5225072251.jpg

查看钉钉开发文档,它给出了两个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();
}

复制代码

原文出处:https://www.cnblogs.com/zhang90030/p/9569515.html

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP