钉钉 H5 鉴权 php + uniapp(h5)+vue (官方文档步骤杂乱)

php

1.钉钉集成类

  /**
   * 获取jsapi_ticket
   */
  public static function get_app_jsapi_ticket()
  {
    $token = self::getaccess_token();
    // $jsapiTicket = '';
    if (Cache::get('jsapiTicket')) {
      $jsapiTicket = Cache::get('jsapiTicket');
    } else {
      $res = (new GuzzleHttpRequester())->post('https://api.dingtalk.com/v1.0/oauth2/jsapiTickets', [], ['content-Type' => 'application/json', 'x-acs-dingtalk-access-token' => $token]);
      if (isset($res['jsapiTicket']) && !empty($res['jsapiTicket'])) {
        $jsapiTicket = $res['jsapiTicket'];
        Cache::set('jsapiTicket', $jsapiTicket, 7199);
      }
    }
    return $jsapiTicket;
  }
  /**
   * 计算dd.config的签名参数
   *
   * @param string $jsticket 通过微应用appKey获取的jsticket
   * @param string $nonceStr 自定义固定字符串
   * @param int $timeStamp 当前时间戳
   * @param string $url 调用dd.config的当前页面URL
   * @return string
   */
  public static function sign($nonceStr, $timeStamp, $url)
  {
    $jsticket = self::get_app_jsapi_ticket();
    $plain = "jsapi_ticket={$jsticket}&noncestr={$nonceStr}&timestamp={$timeStamp}&url=" . self::decodeUrl($url);
    try {
      $sha1 = hash('sha256', $plain, true);
      return byteToHex($sha1);
    } catch (\Exception $e) {
      throw new \Exception($e->getMessage());
    }
  }
  /**
   * 因为ios端上传递的url是encode过的,android是原始的url。开发者使用的也是原始url,
   * 所以需要把参数进行一般urlDecode
   *
   * @param string $url
   * @return string
   */
  private static function decodeUrl($url)
  {
    $parsedUrl = parse_url($url);
    $urlBuffer = $parsedUrl['scheme'] . '://';
    if (isset($parsedUrl['user']) && isset($parsedUrl['pass'])) {
      $urlBuffer .= $parsedUrl['user'] . ':' . $parsedUrl['pass'] . '@';
    }
    if (isset($parsedUrl['host'])) {
      $urlBuffer .= $parsedUrl['host'];
    }
    if (isset($parsedUrl['port'])) {
      $urlBuffer .= ':' . $parsedUrl['port'];
    }
    if (isset($parsedUrl['path'])) {
      $urlBuffer .= $parsedUrl['path'];
    }
    if (isset($parsedUrl['query'])) {
      $urlBuffer .= '?' . urldecode($parsedUrl['query']);
    }
    return $urlBuffer;
  }

2.相关的公共函数

  /**字节数组转化成十六进制字符串 */
  function byteToHex($hash)
  {
    return bin2hex($hash);
  }
//生成大写随机
function generateRandomString($length,$characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
{
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, strlen($characters) - 1)];
    }
    return $randomString;
}

3.调用钉钉集成类接口

  /**钉钉鉴权接口 */
  public static function ddJSAPIAuthentication()
  {
    $params = request()->post();
    $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    $nonceStr = generateRandomString(16, $characters);
    $timeStamp = time();
    $url = $params['url'];
    $signature = (new DingTalk())->sign($nonceStr, $timeStamp, $url);
    echo "Signature: " . $signature;
    return sparkSuccess(dataReturn(0, '生成签名成功!', [
      'nonceStr' => $nonceStr,
      'timeStamp' => $timeStamp,
      'signature' => $signature
    ]));
  }

uniapp

//调用函数
async ddJSAPIAuthentication ({ state, commit }) {
      let url = location.href.split('#')[0];
      let res = await fetch.sr.post('common/Login/ddJSAPIAuthentication', {
        body: {
          url,
        }
      });
      util.ddConfigJSAPI(res.data);
    }
鉴权函数
  /**钉钉鉴权 */
  ddConfigJSAPI (data) {
    dd.config({
      agentId: '', // 必填,微应用ID
      corpId: "",//必填,企业ID
      timeStamp: data.timeStamp, // 必填,生成签名的时间戳
      nonceStr: data.nonceStr, // 必填,自定义固定字符串。
      signature: data.signature, // 必填,签名
      type: 0 / 1,   //选填。0表示微应用的jsapi,1表示服务窗的jsapi;不填默认为0。该参数从dingtalk.js的0.8.3版本开始支持
      jsApiList: [
        'device.geolocation.get'
      ] // 必填,需要使用的jsapi列表,注意:不要带dd。
    });
    dd.error(function (err) {
      uni.showToast({ title: `dd error:${JSON.stringify(err).message}-钉钉鉴权失败,无法定位等,请联系管理员,或重新尝试!`, icon: 'none', duration: 4000 })
    })//该方法必须带上,用来捕获鉴权出现的异常信息,否则不方便排查出现的问题
  }

使用需要鉴权的钉钉接口

    getParseAddress() {
      return new Promise((resolve, reject) => {
        if (dd.env.platform === "notInDingTalk") {
          uni.showToast({
            title: "非钉钉环境",
            icon: "error",
          });
          reject("非钉钉环境");
        } else {
          try {
            dd.ready(function () {
              dd.device.geolocation.get({
                targetAccuracy: 200,
                coordinate: 1,
                withReGeocode: true,
                useCache: false, //默认是true,如果需要频繁获取地理位置,请设置false
                onSuccess: function (result) {
                  uni.showToast({
                    title: JSON.stringify(result),
                    icon: "none",
                  });
                  this.location.position = result.address;
                  this.location.longitude = result.longitude;
                  this.location.latitude = result.latitude;
                },
                onFail: function (err) {
                  uni.showToast({
                    title: "获取失败信息" + JSON.stringify(err),
                    icon: "none",
                  });
                },
              });
            });
          } catch (e) {
            console.log("错误捕捉:", e);
            uni.showToast({ title: JSON.stringify(e), icon: "none" });
            reject("报错");
          }
        }
      });
    },

钉钉npm包

import * as dd from "@/node_modules/dingtalk-jsapi";

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值