釘釘微應用的免登錄流程


  最近做了個釘釘企業內部微應用的項目。記錄下自己的心得。

  首先根據官方文檔明白免登流程

  免登錄的流程如上。首先我們需要拿到自己企業的corpId,和corpSecret,訪問企業后台https://oa.dingtalk.com/index.htm#/microApp/microAppList登錄后就可以拿到(當然你得有管理員權限),拿到這兩個參數后,通過調用釘釘的接口,我們就可以拿到令牌了,也就是access_Token。根據官方文檔的的說明,申請一個access_Token的有效時間是兩個小時,同時該接口對每分鍾的訪問量有限制,所以最好請求到緩存在本地。代碼如下。

  

function getToken(){
		if(Session::has('dingToken')){
			$accessToken = Session::get('dingToken');
		}else{
			$corpId = config('ding.CorpId');
			$corpSecret = config('ding.CorpSecret');
			$urlToken = "https://oapi.dingtalk.com/gettoken?corpid=$corpId&corpsecret=$corpSecret";
			$resToken = apiGet($urlToken);
			$resToken = json_decode($resToken,true);
			$accessToken = $resToken['access_token'];
			Session::set('dingToken',$accessToken);
		}
		return $accessToken;
	}

  在登錄前,首先要在前端引入釘釘的js文件,以前釘釘的js是要分pc端與移動端的,引入的js也不一樣,pc端為前綴為dingTalkPc,移動端前綴為dd。但是釘釘前不久有重新更新了開發文檔,將兩種js合並在了一起,通過傳入type參數區分設備,如下圖代碼所示。

dd.config({
        agentId: "{$data['agentId']}", // 必填,微應用ID
        corpId: "{$data['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 : [
            'runtime.info',
            '​runtime.permission.requestAuthCode',
            'device.notification.confirm',
            'device.notification.alert',
            'device.notification.prompt',
            'biz.ding.post',
            'biz.util.uploadImage',
        ] // 必填,需要使用的jsapi列表,注意:不要帶dd。
    });

  js的地址我就不寫了,開發文檔中有。上面的代碼在釘釘開發文檔中稱之為鑒權。在釘釘的api中有部分api必須是要先進行鑒權才能調用的,而有部分則不需要。為什么要說這個呢。因為有兩種免登的方式,一種比較簡單,一種比較復雜。相信你也猜到了,簡單的不需要鑒權,而復雜的需要鑒權。這兩種方式也互有利弊。

  我們先來說簡單的。當我們拿到access_Token后就可以進行免登了。在頁面中引入釘釘的js文件后,調用js中的api,如下

dd.ready(function() {
    dd.runtime.permission.requestAuthCode({
        corpId: "corpid",
        onSuccess: function(result) {
        {
            code: 'hYLK98jkf0m' //string authCode
        }
        },
        onFail : function(err) {}
  
    });
});

  這個api是不用鑒權的,需要你把corpId傳到前台來,當頁面加載完成后自動執行,執行成功后會返回code碼,值得一提的是釘釘做了限制,它的jsapi只能在釘釘應用中訪問,所以如果直接在瀏覽器中查看時沒有效果的,所以如果你要在電腦上調試,就需要下載一個RC版的釘釘,打開釘釘后,在瀏覽器中輸入http://localhost:16888/就可以在瀏覽器中看到控制台了,手機上的話同樣也有開發版的釘釘app,在app設置中打開調試模式,開啟手機usb調試權限,通過下圖中google瀏覽器的工具來捕捉輸出。

  回歸正題,通過釘釘的jsapi拿到code,code也是有過期時間的,為5分鍾有效時間。拿到code后將code傳回后台加上access_Token訪問釘釘的免登api,驗證成功后返回用戶信息,其中就有用戶的唯一標識Id,再使用拿到de用戶Id加上access_Token訪問另外一個api,代碼如下。

public function getUserInfo(){
        //code
        $data = input();
        $code = $data['code'];

        //Access_Token
        $accessToken = getToken();

        //userId
        $urlId = "https://oapi.dingtalk.com/user/getuserinfo?access_token=$accessToken&code=$code";
        $resId = apiGet($urlId);
        $resId = json_decode($resId,true);
        $userId = $resId['userid'];

        //登錄用戶信息
        $urlInfo = "https://oapi.dingtalk.com/user/get?access_token=$accessToken&userid=$userId";
        $resInfo = apiGet($urlInfo);
        $resInfo = json_decode($resInfo);
        $resInfo = get_object_vars($resInfo); 
}

  就此,免登錄完成了。當然這種方法也有缺陷,那就是返回的用戶信息比較少,不是那么全面。只能拿到如下參數

  如果需要更多的用戶信息,那我們就需要進行比較復雜的免登方式了。也就是說我們在請求用戶信息前必須進行一次鑒權,才能拿到更多的用戶信息。回到拿到access_Token的開頭,我們從后端開始,從一開始的流程圖來看,鑒權需求ticket,nonceStr,timeStamp,signature,agentId,corpId這六個參數agentId和corpId是直接可以拿到的,不再贅述,ticket帶上accessToken參數通過接口獲得,noceStr用於生成密鑰的參數,我是直接給的隨機數。timeStamp當前時間戳,而

signature則是上述幾個參數通過一定算法得到。

function ddconfig(){
    //Access_Token
    $accessToken = getToken();
    // $accessToken = "08bbf680be4f3a028aa652e75a0ad754";

    //ticket
    $urlTicket = "https://oapi.dingtalk.com/get_jsapi_ticket?access_token=$accessToken";
    $resTicket = apiGet($urlTicket,false);
    $resTicket = json_decode($resTicket,true);
    $ticket = $resTicket['ticket'];

    //signature
    $nonceStr = md5(rand(10000000,99999999));
    $agentId = 181397144;
    $timeStamp = time();
    $url = get_current_url();

    $plain = 'jsapi_ticket=' . $ticket .
        '&noncestr=' . $nonceStr .
        '&timestamp=' . $timeStamp .
        '&url=' . $url;
    $signature = sha1($plain);

    $corpId = config('ding.CorpId');

    $data['nonceStr'] = $nonceStr;
    $data['agentId'] = $agentId;
    $data['timeStamp'] = $timeStamp;
    $data['url'] = $url;
    $data['signature'] = $signature;
    $data['corpId'] = $corpId;

    return $data;
}

  拿到這幾個參數后將其返回到前端頁面。首先進行釘釘鑒權,代碼前面已經貼過,值得注意的是鑒權過程中需要初始化jsapi,只有初始化了的jsapi在后面才能被調用,鑒權后的過程就跟第一種方法一樣,拿着返回的code碼,請求userId和用戶信息。最終可以拿到用戶的完整信息。再通過與自己數據庫的數據作對比就完成了免登。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM