关于钉钉H5微应用的免登问题

983 阅读2分钟

背景

最近在研发一个基于钉钉平台的H5微应用项目,我们做的是企业内部应用,但业务内部还是需要用户信息,所以就需要对接钉钉提供的免登API

钉钉开发平台详细介绍了H5微应用的系统免登流程,详情参考地址:open.dingtalk.com/document/or…

我这里主要介绍一下具体实现。

步骤一:封装登录工具类

上代码

import {reactive} from 'vue'
import * as dd from 'dingtalk-jsapi'
import { useEnv } from '@/hooks/useEnv'
import { getToken,getUserInfo,getUser } from '@/apis/modules/dingding/ddApi'
import { queryURLParams } from '@/utils/urlParams'
import ddConfig from '@/config/dd.config'


/**
 * 钉钉自动登录
 */

const data:any = reactive({
    userName:'',
    roleList:[],
    spinner:true
})

let accessToken = ""
let authCode = ""
let userId = ""

dd.ready(function () {
    const logon = async () => {
        console.log("获取免登授权码开始----------------")
        await getAuthCode()
        console.log("获取免登授权码完成----------------")
        console.log("获取acess_token开始----------------")
        await getTokenFn()
        console.log("获取acess_token完成----------------")
        console.log("获取用户信息开始----------------")
        await getUserInfoFn()
        console.log("获取用户信息完成----------------")
        console.log("获取用户信息详情开始----------------")
        await getUserFn()
        console.log("获取用户信息详情完成----------------")
        data.spinner = false
    }
    logon()
})

//1、获取免登授权码authcode
function getAuthCode(){
    const { VITE_DINGDING_CORPID } = useEnv()
    const pro = dd.runtime.permission.requestAuthCode({
        corpId: VITE_DINGDING_CORPID,//企业id
    })
    pro.then(res => {
        if (res.code && res.code !== "") {
            console.log("authcode:",res.code)
            authCode = res.code
        }
    })
    return pro
}

//2、获取acess_token
const appType = queryURLParams(window.location.href)["appType"]
function getTokenFn() {
    const param = {
        appkey: ddConfig[appType]["appKey"],
        appsecret: ddConfig[appType]["appSecret"]
    }
    const pro = getToken(param)
    pro.then(res => {
        if (res.data.errcode === 0 && res.data.access_token !== "") {
            console.log("access_token:",res.data.access_token)
            accessToken = res.data.access_token
        }
    })
    return pro
}

//3、获取用户基本信息 userId
function getUserInfoFn(){
    const param = {
        access_token:accessToken,
        code:authCode
    }
    const pro = getUserInfo(param)
    pro.then(res=>{
        if(res.status === 200 && res.data.errcode === 0 && res.data.result){
            data.userName = res.data.result.name
            userId = res.data.result.userid
        }
    })
    return pro
}

//4、获取用户信息详情
function getUserFn(){
    const param = {
        access_token:accessToken,
        userid:userId
    }
    const pro = getUser(param)
    pro.then(res=>{
        if(res.status === 200 && res.data.errcode === 0 && res.data.result){
            data.roleList = res.data.result.role_list
        }
    })
    return pro
}

export default data

这里面的ddApi封装了免登所需要的钉钉提供的接口函数:

ddApi.ts
/**
 * 钉钉API
 */
import { http } from '@/apis/http'
import querystring from 'querystring'
// 获取企业内部应用的access_token
export function getToken(params: any) {
  return http.get('/dingding/gettoken', {
    params: params,
  })
}

// 获取基本信息 用户userid
export function getUserInfo(param) {
  return http.post(
    '/dingding/topapi/v2/user/getuserinfo',
    querystring.stringify(param)
  )
}

// 获取用户信息详情
export function getUser(param) {
  return http.post(
    '/dingding/topapi/v2/user/get',
    querystring.stringify(param)
  )
}

这里面值得注意的是“获取用户信息详情”接口,因为此接口需要授权,否则调用就会报错:

image.png 此时我们需要到钉钉开发者后台权限管理进行查询requiredScopes配置即可:

image.png

步骤二 引用

在App.vue中,我们引入创建好的工具类,在页面中写好需要的属性

上面的权限申请成功后,我们再试一下,发现可以成功获取用户信息了:

image.png

当我们拿到用户信息后,最好是存入localstorage或者cookie等前端缓存中,避免每次进入都需要调用这一套免登流程。