钉钉内集成第三方免密登录(Vue+.Net)

需要实现的效果就是在钉钉内点击应用能跳转到第三方网站并且免密登录

1.登录钉钉PC端管理后台

2.通过管理后台进去开发者后台

3.应用开发 创建H5微应用

4.应用创建成功后直接点权限管理全部授权

5.设置H5登录地址

  1. 应用管理发布

至此需要配置的步骤全部已完成,需要记住已下三个参数后续开发时候会用到

Client ID、Client Secret、CorpId

上代码

前端用的VUE

html 复制代码
// 1.需要下载钉钉包
npm install dingtalk-jsapi --save

// 2.引入包
import * as dd from 'dingtalk-jsapi';

// 3.编写相关登录逻辑
async function initDD() {
  //判断是不是通过钉钉内打开的应用
  if (dd.env.platform !== "notInDingTalk") {
    //进行钉钉登录操作
    dd.ready(() => {
      //获取登录一次性凭证
      dd.runtime.permission.requestAuthCode({
        corpId: '换成自己对应的参数以上有说明', // 企业id
      }).then(ddRes => {
        //凭证获取成功后调用后端登录接口完成相关自动登录逻辑
        loginDingTalk(ddRes.code).then(res => {
          //记录应用登录凭证到本地
          userStore.updateToken(res.data.data.token);
          nextTick(() => {
            //跳转到主页
            router.push(PageEnum.BASE_HOME);
          });
        });
      }).catch(err => {
        alert(JSON.stringify(err));
      });
    });
  }
}

后端.NET

WebApi 接口

cs 复制代码
    /// <summary>
    /// 用户登录.
    /// </summary>
    /// <returns></returns>
    [HttpPost("Login/DingTalk/{code}")]
    [AllowAnonymous]
    [IgnoreLog]
    public async Task<dynamic> LoginDingTalk(string code)
    {
        DingUtil ding = new DingUtil();
        //得到企业访问token
        string accessToken = ding.GetDingToken("Client ID对应自己应用", "Client Secret对应自己应用");
        //得到当前钉钉登录的用户信息
        string strObj = ding.GetUserInfoInApp(code, accessToken);
        
        JObject objData = strObj.ToObject();

        //通过钉钉移动电话获取第三方本地用户信息
        UserEntity userEntity = await _userRepository.GetFirstAsync(x => x.MobilePhone.Equals(objData["Mobile"]));

        if (userEntity == null) throw Oops.Bah("当前应用无账号,请联系管理员");
        
        //获取到用户信息后完成自动登录相关逻辑 并返回第三方应用登录凭证给登录界面进行缓存
        var loginInput = await GetUserInfoByUserAccount(userEntity.Account);
        var result = await Login(loginInput);
        return new { code = 200, data = result };
    }
cs 复制代码
using DingTalk.Api;
using DingTalk.Api.Request;
using DingTalk.Api.Response;
using Mapster;
using Minio.DataModel.Tracing;
using NetTaste;
using Org.BouncyCastle.Ocsp;
using System.Text.RegularExpressions;
using Tea;
using static DingTalk.Api.Request.OapiRobotSendRequest;
using static DingTalk.Api.Response.OapiV2DepartmentListsubResponse;
using static DingTalk.Api.Response.OapiV2UserListResponse;

namespace DingDing;

/// <summary>
/// 钉钉.
/// </summary>
public class DingUtil
{
    /// <summary>
    /// 访问令牌.
    /// </summary>
    public string token { get; private set; }

    /// <summary>
    /// token有效时间.
    /// </summary>
    public TimeSpan expiresTime { get; private set; }

    /// <summary>
    /// 构造函数.
    /// </summary>
    /// <param name="appKey">企业号ID.</param>
    /// <param name="appSecret">凭证密钥.</param>
    public DingUtil(string appKey, string appSecret)
    {
        token = GetDingToken(appKey, appSecret);
    }

    /// <summary>
    /// 构造函数.
    /// </summary>
    /// <param name="appKey">企业号ID.</param>
    /// <param name="appSecret">凭证密钥.</param>
    public DingUtil()
    {
    }

    /// <summary>
    /// 钉钉token.
    /// </summary>
    /// <param name="appKey">企业号ID.</param>
    /// <param name="appSecret">凭证密钥.</param>
    /// <returns></returns>
    public string GetDingToken(string appKey, string appSecret)
    {
        try
        {
            var tokenurl = "https://oapi.dingtalk.com/gettoken";
            DefaultDingTalkClient client = new DefaultDingTalkClient(tokenurl);
            OapiGettokenRequest req = new OapiGettokenRequest();
            req.SetHttpMethod("GET");
            req.Appkey = appKey;
            req.Appsecret = appSecret;
            OapiGettokenResponse response = client.Execute(req);
            if (response.Errcode == 0)
            {
                // 过期时间
                expiresTime = DateTime.Now.Subtract(DateTime.Now.AddSeconds(response.ExpiresIn));
                return response.AccessToken;
            }
            else
            {
                throw new Exception("获取钉钉Token失败,失败原因:" + response.Errmsg);
            }

        }
        catch (Exception ex)
        {

            return string.Empty;
        }
    }


    public string GetUserInfoInApp(string code, string accessToken)
    {
        var client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getuserinfo");
        OapiV2UserGetuserinfoRequest req = new OapiV2UserGetuserinfoRequest();
        req.Code = code;
        OapiV2UserGetuserinfoResponse rsp = client.Execute(req, accessToken);
        if (rsp.Errcode == 0)
        {
            // 根据unionid获取userid
            string unionid = rsp.Result.Unionid;
            DefaultDingTalkClient clientDingTalkClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/getbyunionid");
            OapiUserGetbyunionidRequest reqGetbyunionidRequest = new OapiUserGetbyunionidRequest();
            reqGetbyunionidRequest.Unionid = unionid;
            OapiUserGetbyunionidResponse oapiUserGetbyunionidResponse = clientDingTalkClient.Execute(reqGetbyunionidRequest, accessToken);
            if (oapiUserGetbyunionidResponse.Errcode == 0)
            {
                // 根据userId获取用户信息
                string userid = oapiUserGetbyunionidResponse.Result.Userid;
                var user = GetUserInfoByUserId(userid, accessToken);
                return user;
            }
        }

        return string.Empty;
    }

    /// <summary>
    /// 根据用户UserId取得用户信息.
    /// </summary>
    /// <param name="userId"></param>
    /// <returns></returns>
    private string GetUserInfoByUserId(string userId, string accessToken)
    {
        var client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
        var req = new OapiV2UserGetRequest();
        req.Userid = userId;
        req.Language = "zh_CN";
        var res = client.Execute(req, accessToken);

        if (res.Errcode == 0) return res.Result.ToJsonString(); else throw new Exception(res.ErrMsg);
    }
    #region 用户
}
相关推荐
市象6 小时前
钉钉向广告低头
互联网·钉钉·企业办公
国通快递驿站1 天前
AntFlow一款开源免费且自主可控的仿钉钉工作流引擎
开源·钉钉·antflow
Dark_programmer1 天前
uni-app - - - - - 钉钉小程序 uni.showToast回调函数不执行问题(PC端钉钉小程序 接口API回调函数不执行)
小程序·uni-app·钉钉
weixin_449310844 天前
利用钉钉与金蝶云星空进行付款单自动化集成
运维·自动化·钉钉
CL_IN5 天前
钉钉日常报销单与金蝶云星空集成技术详解
前端·数据库·钉钉
猫姐°5 天前
python实现钉钉群机器人消息通知(消息卡片)
python·机器人·钉钉
凉风听雪6 天前
钉钉平台开发小程序
小程序·钉钉·开发者工具
大风起兮云飞扬丶7 天前
钉钉接入自定义机器人
机器人·钉钉
chuk.7 天前
【JAVA】利用钉钉自定义机器人监控NACOS服务,实现实时下线通知
java·机器人·钉钉