php钉钉扫码登陆实现

一、钉钉配置

  1. 登陆钉钉管理者后台,创建一个h5微应用;
  2. 查看并记录应用的Appkey和AppSecret;
    在这里插入图片描述
  3. 配置服务器出口IP和首页地址;
    出口IP可配置多个,用","隔开,本机开发的话需有配置127.0.0.1以及本机ip(可通过百度本机ip获取)
    在这里插入图片描述
  4. 扫码后回调地址设置;
    即需要写php代码的那个文件方法
    在这里插入图片描述
  5. 权限配置;
    如果需要获取用户的具体信息就配置通讯录权限,需要什么权限申请开通什么权限
    在这里插入图片描述

二、前端二维码生成

html:写个空div块用来放二维码

<div id="dindinCode">
</div>

js:需引入js文件以及进行处理

<script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script>
<script>
	$(document).ready(function() {
		//初始的时候即调用
        login();
    });
    function login(){
        this.showCode = true
        var url   = encodeURIComponent('配置的回调地址');
        var appid = '保存的应用的appKey';
        var goto = encodeURIComponent('https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=' + appid + '&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=' + url);
        var obj = DDLogin({
            id: "dindinCode", //在HTML标签定义的空div块的id
            goto: goto,
            style: "border:none;background-color:#FFFFFF;",
            width: "270",//二维码的宽度 自行调整
            height: "300"//二维码的高度 自行调整
        });
        var hanndleMessage = function(event) {
            var origin = event.origin;
            if (origin == "https://login.dingtalk.com") {
                var loginTmpCode = event.data; //获取loginTmpCode后跳转
                localStorage.setItem('ddlogin', 'success')
                window.location.href = "https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=" + appid + "&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=" + url + "&loginTmpCode=" + loginTmpCode;
            }
        };
        if (typeof window.addEventListener != "undefined") {
            window.addEventListener("message", hanndleMessage, false);
        } else if (typeof window.attachEvent != "undefined") {
            window.attachEvent("onmessage", hanndleMessage);
        }
    }
</script>

三、php回调方法

  1. 先去钉钉开放平台下载phpSDK
    链接:https://open.dingtalk.com/document/orgapp/obtain-the-user-information-based-on-the-sns-temporary-authorization
    在这里插入图片描述
    2.php回调方法:
    /**
     * 通过钉钉扫码登陆回调方法
     * @param string  $code
     * @param string  $state
     * */
    public function dindinlogin($code = '', $state = ''){
        include "./TopSdk.php";
        $AppKey    = '保存的应用的appKey';
        $AppSecret = '保存的应用的appSecret';

        //输出日志记录
        $file_name = "./log.php";
        file_put_contents($file_name, 'Code: ' . $code . '    ' . date("Y-m-d H:i:s", time()) . "\n" . "\n", FILE_APPEND);

        // 第一步 : 获取access_token,access_token有效期为7200秒,有效期内重复获取会返回相同结果并自动续期,过期后再获取会返回新的access_token
        $token_file_name = "./access_token.php";
	    if(file_exists($token_file_name)){
	        $token_file_content = json_decode(trim(substr(file_get_contents($token_file_name), 15)));
	        //token超时
	        if($token_file_content->expire_time < time()){
	            //从接口获取token
	            $access_token = $this->getDindinToken($AppKey,$AppSecret,$token_file_name);
	        }else{
	            //否则使用缓存的token
	            $access_token = $token_file_content->access_token;
	        }
	    }else{
	        //接口获取token
	        $access_token = $this->getDindinToken($appkey,$appsecret,$token_file_name);
	    }
        file_put_contents($file_name, 'access_token: ' . $access_token . '    ' . date("Y-m-d H:i:s", time()) . "\n" . "\n", FILE_APPEND);

        // 第二步 : 根据临时授权码Code获取用户unionid
        $post_curl = new DingTalkClient(DingTalkConstant::$CALL_TYPE_OAPI, DingTalkConstant::$METHOD_POST, DingTalkConstant::$FORMAT_JSON);
        $unionid_request = new OapiSnsGetuserinfoBycodeRequest;
        $unionid_request->setTmpAuthCode($code);
        $unionid_info = $post_curl->executeWithAccessKey($unionid_request, "https://oapi.dingtalk.com/sns/getuserinfo_bycode", "$AppKey", "$AppSecret");
        if (!empty($unionid_info)) {
            file_put_contents($file_name, 'unionid_info: ' . json_encode($unionid_info) . '    ' . date("Y-m-d H:i:s", time()) . "\n" . "\n", FILE_APPEND);
        }

        // 第三步 : 根据unionid获取用户userid
        $userid_request = new OapiUserGetbyunionidRequest;
        $unionid = $unionid_info->user_info->unionid;
        $userid_request->setUnionid($unionid);
        $userid_info = $post_curl->execute($userid_request, $access_token, "https://oapi.dingtalk.com/topapi/user/getbyunionid");
        if (!empty($userid_info) && $userid_info->errcode == 0) {
            file_put_contents($file_name, 'userid_info: ' . json_encode($userid_info) . '    ' . date("Y-m-d H:i:s", time()) . "\n" . "\n", FILE_APPEND);
        }

        // 第四步 : 根据userid获取用户钉钉信息
        $userinfo_request = new OapiV2UserGetRequest;
        $userid = $userid_info->result->userid;
        $userinfo_request->setUserid($userid);
        $userinfo = $post_curl->execute($userinfo_request, $access_token, "https://oapi.dingtalk.com/topapi/v2/user/get");
        if (!empty($userinfo)) {
            file_put_contents($file_name, 'userinfo_responce_string: ' . json_encode($userinfo) . '    ' . date("Y-m-d H:i:s", time()) . "\n" . "\n", FILE_APPEND);
        }
        echo "<pre>";var_dump($userinfo);die();
    }
    
/**
 * 获取钉钉AccessToken 回调方法里面用到的方法
 *
 * @param string  $appkey
 * @param string  $appsecret
 * @param string  $token_file_name
 * @access public
 * @return void
 * */
public function getDindinToken($appkey, $appsecret, $token_file_name){
    $url = "https://oapi.dingtalk.com/gettoken?appkey=".$appkey."&appsecret=".$appsecret;
    $get_result = json_decode($this->http($url),true);
    if($get_result['errcode'] == '0'){
        $new_token = (object)[];
        $token = $get_result['access_token'];
        $new_token->expire_time = time() + 7000;
        $new_token->access_token = $token;
        $this->set_php_file($token_file_name,json_encode($new_token));
    }else{
        $token = 'get_token_error';
    }
    return 	$token;
}

/**
 * 发送http请求 回调方法里面用到的方法
 *
 * @param string  $url
 * @param array   $data
 * @access public
 * @return void
 * */
public function http($url,$data = null){
    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_HEADER, 0);
    if(!empty($data)){
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    }
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_TIMEOUT, 500);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($curl, CURLOPT_URL, $url);
    $res = curl_exec($curl);
    curl_close($curl);
    return $res;
}

/**
 * 设置php文件 回调方法里面用到的方法
 *
 * @param string  $filename
 * @param string  $content
 * @access public
 * @return void
 * */
public function set_php_file($filename,$content) {
   $fp = fopen($filename, "w");
   fwrite($fp, "<?php exit();?>" . $content);
   fclose($fp);
   return;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值