专栏首页小白程序猿钉钉扫码登录-PHP版本

钉钉扫码登录-PHP版本

今天写了一个第三方登录的功能,使用的是钉钉,实现的功能就是打开网页,使用的钉钉APP扫描二维码,快捷登录网站,下面一起来看一下!

钉钉开放平台

首先,登录管理后台,点击右上角进行登录,这里的登录需要是管理员身份或者授权权限的子管理员身份,其他的身份不好使,如果没有管理员身份或子管理员身份(如我一样),那么就只能自己创建一个团队了,里面邀请了好友就可以了。这样你就是拥有管理员身份了。继而可以登录这个管理后台了(第一次登录需要设置个密码,后续登录时需要输入的)。

创建应用

进入管理页面后,我们进入应用开发菜单,找到最下方的“移动接入应用”,进入子级菜单中的“登录”,在里面创建一个应用。如下图:

创建应用后,回到页面中,我们可以看到 appid 和 appSecret 这两项参数,后续我们会用到。

授权流程

第三方发起钉钉授权登录请求,钉钉用户允许授权第三方应用后,钉钉会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数。

通过code调用接口getuserinfo_bycode获取授权登录用户信息。

构造扫码登录页面

构建登录页面有两种方式,我们以跳转方式为例,这种方式使用得较多,也非常方便。在企业Web系统里,用户点击使用钉钉扫描登录,第三方Web系统跳转到如下地址:地址就不做展示了,说一下地址的参数:

获取用户信息

首先说一下,我们获取到的用户信息只有三项,如下表:

但是在下午的实际测试中发现,接口返回的值还多了两项,文档中没有做出说明,猜测是权限字段和权限标识字段。

在获取用户信息时我们要使用到的参数有如下:

在请求的时候需要使用POST方式并传递数据,数据如下:

{"tmp_auth_code": "23152698ea18304da4d0ce1xxxxx"}

这里需要注意一点,传递数据为json格式,如果使用CURL进行请求时会出现post请求数据格式错误的提示,我们需要在curl请求头上面做出说明,代码如下:

$header = [ "Content-Type: application/json; charset=utf-8", "Content-Length:" . strlen(json_encode($postFields)) ];
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);

代码

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2020/4/3 0003
 * Time: 11:27
 */

namespace app\controller;

use think\Controller;

class Login extends Controller
{
    /**
     * 登录
     * @return \think\response\View
     */
    public function index()
    {
        // 临时关闭模板布局
        $this->view->engine->layout(false);
        return view("login/index");
    }

    public function out()
    {
    }


    public function back()
    {
        $code  = input('get.code');
        $state = input('get.state');
        if(!$code or !$state) {
            $this->error('参数缺失');
        }
        if($state > time()) {
            $this->error('参数异常');
        }

        $accessKey = 'dingoa9f8qj1**********';
        $timestamp = $this->mTime();
        $signature = $this->signature($timestamp);
        $url       = 'https://oapi.dingtalk.com/sns/getuserinfo_bycode?accessKey=' . $accessKey . '&timestamp=' . $timestamp . '&signature=' . $signature;
        $data      = [ 'tmp_auth_code' => $code ];
        $userInfo  = $this->curl_json($url, $data);
        $res       = json_decode($userInfo, true);

        if(isset($res['errcode']) and $res['errcode'] == 0) {
            //登录成功
            echo 1;
        }
    }


    /**
     * 计算签名
     * @param $timestamp
     * @return string
     */
    public function signature($timestamp)
    {
        // 根据timestamp, appSecret计算签名值
        $s                   = hash_hmac('sha256', $timestamp, '**********G6KaiRey7NFJxXHyBthsPL5Q4rBSvlJhQvREadhO__uHhDs', true);
        $signature           = base64_encode($s);
        $urlEncode_signature = urlencode($signature);
        return $urlEncode_signature;
    }

    /**
     * 毫秒级时间戳
     * @return float
     */
    public function mTime()
    {
        list($s1, $s2) = explode(' ', microtime());
        $mTime = (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
        return $mTime;
    }

    public function curl_json($url, $postFields = null)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_FAILONERROR, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_USERAGENT, "dingtalk-sdk-php");
        //https 请求
        if(strlen($url) > 5 && strtolower(substr($url, 0, 5)) == "https") {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }
        curl_setopt($ch, CURLOPT_POST, true);
        $header = [ "Content-Type: application/json; charset=utf-8", "Content-Length:" . strlen(json_encode($postFields)) ];
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postFields));
        $reponse = curl_exec($ch);
        if(curl_errno($ch)) {
            throw new Exception(curl_error($ch), 0);
        } else {
            $httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            if(200 !== $httpStatusCode) {
                throw new Exception($reponse, $httpStatusCode);
            }
        }
        curl_close($ch);
        return $reponse;
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 微信小程序开发-注册账号

    微博登录原理,简单介绍一下,通过特定网址携带固定参数,发起请求登录,之后通过回调地址,获取code值,通过code值获取access_token值和uid值,通...

    申霖
  • PHP实现下载远程图片保存到本地

    日常开发过程中,可能会遇到需要通过程序(代码)将网络图片下载到本地或上传至存储空间,下面我们看一组代码。

    申霖
  • 如何通过IP地址获取用户所在城市?

    在日常开发过程中,经常有通过IP去获取用户位置,或在服务器日志中查看到各种各样的ip地址,如何通过ip地址去获取用户的信息呢?比如所在城市,网络提供商是联通,移...

    申霖
  • 获取lofter官方首页背景壁纸

    墨渊
  • TP3.2接入极光IM

    一:在common/common文件下function文件中写一个公共调用的方法。

    php007
  • 微信域名检测API接口PHP源码

    从这里可以看出,检测域名是否被微信屏蔽,是这里的核心。但是在网上搜索和查看微信的文档,微信官方没有提供相关的查询方法。分享一个接口地址,分享给有需要的朋友。

    墨渊
  • 微信域名检测API接口PHP代码

    从这里可以看出,检测域名是否被微信屏蔽,是这里的核心。但是在网上搜索和查看微信的文档,微信官方没有提供相关的查询方法。分享一个接口地址,分享给有需要的朋友。

    Inkedus
  • IP138开放查询接口(公测版),json调用示例

    世纪访客
  • loc刷分

    用户1191760
  • PHP企业付款到零钱

    昨天分享完小程序,今天就要写给用户发红包.之前也写过一次支付.今天也是有幸接触了下企业付款到零钱.企业通过这个可以将钱直接发到用户的零钱里面.

    桑先生

扫码关注云+社区

领取腾讯云代金券