前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >钉钉一键登录(web端)

钉钉一键登录(web端)

原创
作者头像
Java king
发布2023-02-21 15:11:39
2K0
发布2023-02-21 15:11:39
举报
文章被收录于专栏:后端Java

记录一下钉钉一键登录的流程,虽然文档写的很详细,但还是有一些地方写的不是很详细。

流程图:

文档:

获取微应用免登授权码文档:获取微应用免登授权码 - 钉钉开放平台

获取微应用免登授权码接口:API Explorer

获取登录用户的访问凭证:获取登录用户的访问凭证 - 钉钉开放平台

获取用户通讯录个人信息文档:获取用户通讯录个人信息 - 钉钉开放平台

获取用户通讯录个人信息接口:API Explorer

第三方企业应用免登:第三方企业应用免登 - 钉钉开放平台

查看用户详情:查询用户详情 - 钉钉开放平台

获取用户token接口:API Explorer

这里是我整理的一些文档和API在线测试的地址。

首先是进入钉钉的访问凭证,也就是咱们的授权页面,这个是钉钉已经集成好的,咱们只需要更改一下配置就好了。

代码语言:txt
复制
https://login.dingtalk.com/oauth2/auth?
redirect_uri=https%3A%2F%2Fwww.aaaaa.com%2Fa%2Fb
&response_type=code
&client_id=dingbbbbbbb
&scope=openid
&state=dddd
&prompt=consent

咱们重点介绍一下redirect_uri这个参数是干啥的,以及从哪里配置。

配置的地方:

咱们做单点登录肯定是需要把获取的用户信息进行入库的,所以redirect_uri填写咱们的业务接口,除非不需要进行数据绑定只需要跳转页面,这里就可以填写一个页面地址。

我这里是需要进行用户绑定,因此填写的是一个接口地址。

下面的一些参数,参考文档就可以查看详情内容。

接口方式采用Get请求,授权成功之后会从请求后面拼接一个参数。

参数名:authCode这个参数咱们后面会用来获取token

拿到authCode调用获取Token,文档参数介绍的都很详细,唯独coderefreshToken没有过多的介绍。这两个参数从哪里获取?如何使用?

文档没有过多介绍,这里说明:其实这两个参数就是咱们上一步授权获得的authCode这两个参数都填写authCode就可以。其他的参数没有什么异议。

咱们拿到token就可以获取其他的信息。例如获取 用户通讯录个人信息

用户的unionId咱们通过前面的方式,是没有返回的,钉钉也给咱们做了处理可以传me就可以获取当前授权用户的信息。这里说明获取这个是需要授权 权限的。

搜索个人信息,开通标注的两个权限,就可以获取到用户的信息。

咱们获取到手机号和邮箱,就可以写咱们自己的业务逻辑了。

需要注意一个问题,咱们这个接口是钉钉回调的,前端是没办法知道咱们是否成功,所以页面的跳转也是咱们控制的。

如何控制呢,咱们接口返回值使用String

然后使用redirect:重定向咱们需要的页面就可以了。登录失败就可以重定向账号密码页面,登录成功就可以返回咱们的首页或者自定义的页面。

这样流程就走完了。

我这里整理了一个util,帖到下面:

代码语言:java
复制
import com.aliyun.dingtalkcontact_1_0.models.GetUserResponse;
import com.aliyun.dingtalkoauth2_1_0.models.GetUserTokenResponse;
import com.aliyun.tea.TeaException;
import com.aliyun.teautil.models.RuntimeOptions;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiServiceGetCorpTokenRequest;
import com.dingtalk.api.request.OapiV2UserGetuserinfoRequest;
import com.dingtalk.api.response.OapiServiceGetCorpTokenResponse;
import com.dingtalk.api.response.OapiV2UserGetuserinfoResponse;
import com.pdm.core.cache.redis.RedisUtil;
import com.pdm.predamo.basis.constants.SystemCacheConstants;
import com.taobao.api.ApiException;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @author king
 * @date 2022年09月16日 09:34
 */
@Component
public class DingTalkUtil {

    @Resource
    RedisUtil redisUtil;

    public static com.aliyun.dingtalkoauth2_1_0.Client createClientV2() throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkoauth2_1_0.Client(config);
    }

    public static com.aliyun.dingtalkcontact_1_0.Client createClientV1() throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkcontact_1_0.Client(config);
    }


    /**
     * 获取用户Token
     *
     * @param authCode:授权Code,用于获取Token
     * @return GetUserTokenResponse
     * @author king<fsyvip666 @ gmail.com>
     * @date 2022/9/16 10:20
     */
    public static GetUserTokenResponse getUserToken(String authCode) throws Exception {
        com.aliyun.dingtalkoauth2_1_0.Client client = createClientV2();
        com.aliyun.dingtalkoauth2_1_0.models.GetUserTokenRequest getUserTokenRequest = new com.aliyun.dingtalkoauth2_1_0.models.GetUserTokenRequest()
                .setClientSecret(DingtalkConstant.SUITE_SECRET)
                .setClientId(DingtalkConstant.SUITE_KEY)
                .setCode(authCode)
                .setGrantType(DingtalkConstant.REFRESH_TOKEN)
                .setRefreshToken(authCode);
        try {
            return client.getUserToken(getUserTokenRequest);
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性,可帮助开发定位问题
                throw new RuntimeException(err);
            }
        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性,可帮助开发定位问题
                throw new RuntimeException(_err);
            }
        }
        return null;
    }

    /**
     * 获取用户通讯录个人信息
     *
     * @param accessToken : 鉴权Token
     * @return GetUserResponse
     * @author king<fsyvip666 @ gmail.com>
     * @date 2022/9/16 10:31
     */
    public static GetUserResponse getUserInfoByToken(String accessToken) throws Exception {
        com.aliyun.dingtalkcontact_1_0.Client client = createClientV1();
        com.aliyun.dingtalkcontact_1_0.models.GetUserHeaders getUserHeaders = new com.aliyun.dingtalkcontact_1_0.models.GetUserHeaders();
        getUserHeaders.xAcsDingtalkAccessToken = accessToken;
        try {
            return client.getUserWithOptions(DingtalkConstant.ME, getUserHeaders, new RuntimeOptions());
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性
                throw new RuntimeException(err);
            }
        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性
                throw new RuntimeException(_err);
            }
        }
        return null;
    }

我这里使用的是钉钉的SDK,直接引入SDK依赖就好了。

代码语言:java
复制
		<dependency>
			<groupId>com.aliyun</groupId>
			<artifactId>alibaba-dingtalk-service-sdk</artifactId>
			<version>2.0.0</version>
		</dependency>

		<dependency>
			<groupId>com.aliyun</groupId>
			<artifactId>dingtalk</artifactId>
			<version>1.4.33</version>
		</dependency>

就这么简单,到这里就完事了。其他的跟着文档来就好了。

积极向上:下一篇记录一下,钉钉内部第三方应用一键登录

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档