钉钉一键登录第三方网站

简介: 钉钉一键登录第三方网站,这里主要记录一键登录整个实现步骤。登录页面构造好钉钉一键登录链接后的页面效果。

企业内部系统已经做过了钉钉扫码登录,现在需要添加钉钉一键登录第三方网站功能,这里主要记录一键登录整个实现步骤。

钉钉开发者后台

想要实现钉钉一键登录,首先需要在钉钉开放平台管理平台配置H5微应用

H5微应用

实现钉钉一键登录第三方网站,官方文档地址:实现登录第三方网站根据官方文档的操作步骤来看的话需要先到钉钉开发者后台添加H5微应用,钉钉开发者后台地址:钉钉开发者后台进入钉钉开发者后台后,

image.png

选择【企业内部开发】进入

image.png


点击右上角【创建应用】

image.png

输入【应用名称】,【应用描述】,上传系统图标或者不上传都可以,点击【确认创建】

image.png

创建完成之后你就可以看到你创建的H5微应用的应用凭证,点击左侧菜单【权限管理】

image.png

这里需要申请【个人手机号信息】、【通讯录个人信息读权限】两个权限,权限申请完成之后点击菜单【登录与分享】

image.png

在输入框中输入回调的域名及对应的方法,点击【添加】完成回调URL的配置,这里因为是三套环境(开发、测试、线上),所以配置三套回调URL,三套环境用同一套应用凭证,当然你也可以选择创建三个H5微应用来支持三套环境。

应用代码开发

首先需要在登录页构造钉钉一键登录跳转链接,构造链接参考官方文档

image.png

登录页面login.html

登录页面构造好钉钉一键登录链接后的页面效果

image.png

页面代码,在原有的登录页面中添加如下代码

<divstyle="padding-left: 83px;"><buttontype="button"class="btn-dingding"onclick="toDingDing();">钉钉一键授权登录</button></div>


同时在页面增加跳转方法

//钉钉一键授权登录functiontoDingDing() {
varprojectUrl=$("#projectUrl").val();
varh5AppKey=$("#h5AppKey").val();
varredirect_uri=projectUrl+"dingdingOneClickLogin";
redirect_uri=encodeURIComponent(redirect_uri);
self.location="https://login.dingtalk.com/oauth2/auth?redirect_uri="+redirect_uri+"&response_type=code&client_id="+h5AppKey+"&scope=openid&state=&prompt=consent";
}


其中:projectUrl  就是获取的请求域名地址

          h5AppKey 就是配置的H5微应用的AppKey

至此,页面的内容添加完毕,下面开始来增加后台Java方法

登录实现LoginController.java

登录实现controller需要增加如下方法

/*** 登录系统* @param use* @return*/privateStringdoLoginSystem(SysUseruse) {
//已绑定账号则直接登录操作MyUsernamePasswordTokentoken=newMyUsernamePasswordToken(use.getUnionId(), use.getPassword(),false,true);
// 登陆主流程Subjectsubject=SecurityUtils.getSubject();
subject.login(token);
returnredirect("/index");
    }
publicstaticcom.aliyun.dingtalkoauth2_1_0.ClientauthClient() throwsException {
Configconfig=newConfig();
config.protocol="https";
config.regionId="central";
returnnewcom.aliyun.dingtalkoauth2_1_0.Client(config);
    }
/*** 获取用户token* @param authCode* @return* @throws Exception*///接口地址:注意/auth与钉钉登录与分享的回调域名地址一致@RequestMapping(value="/dingdingOneClickLogin", method=RequestMethod.GET)
publicStringgetAccessToken(@RequestParam(value="authCode")StringauthCode) throwsException {
com.aliyun.dingtalkoauth2_1_0.Clientclient=authClient();
GetUserTokenRequestgetUserTokenRequest=newGetUserTokenRequest()
//应用基础信息-应用信息的AppKey,请务必替换为开发的应用AppKey                .setClientId(dingDingProperties.getH5AppKey())
//应用基础信息-应用信息的AppSecret,,请务必替换为开发的应用AppSecret                .setClientSecret(dingDingProperties.getH5AppSecret())
                .setCode(authCode)
                .setGrantType("authorization_code");
GetUserTokenResponsegetUserTokenResponse=client.getUserToken(getUserTokenRequest);
//获取用户个人tokenStringaccessToken=getUserTokenResponse.getBody().getAccessToken();
GetUserResponseBodyuserinfo=getUserinfo(accessToken);
//根据unionId 获取用户信息StringunionId=userinfo.getUnionId();
SysUseruse=sysUserService.selectUserByUnionId(unionId);
Stringmsg="";
if (use!=null) {
returndoLoginSystem(use);
        }else {
//未绑定 则自动添加账号 根据unionid获取useridOapiUserGetbyunionidResponse.UserGetByUnionIdResponseuserIdByUnionIdV2=dingDingService.getUserIdByUnionIdV2(unionId);
if (userIdByUnionIdV2!=null&&StringUtils.isNotEmpty(userIdByUnionIdV2.getUserid())) {
//根据userid获取用户详细信息OapiV2UserGetResponse.UserGetResponseuser=dingDingService.getUserDetailByUserid(userIdByUnionIdV2.getUserid(), null);
if (user!=null) {
returnsaveSysUserAuto(user);
                }else {
msg="one";
                }
            }else {
msg="one";
            }
        }
returnredirect("/login?msg="+msg);
    }
publicstaticcom.aliyun.dingtalkcontact_1_0.ClientcontactClient() throwsException {
Configconfig=newConfig();
config.protocol="https";
config.regionId="central";
returnnewcom.aliyun.dingtalkcontact_1_0.Client(config);
    }
/*** 获取用户个人信息* @param accessToken* @return* @throws Exception*/publicGetUserResponseBodygetUserinfo(StringaccessToken) throwsException {
com.aliyun.dingtalkcontact_1_0.Clientclient=contactClient();
GetUserHeadersgetUserHeaders=newGetUserHeaders();
getUserHeaders.xAcsDingtalkAccessToken=accessToken;
//获取用户个人信息,如需获取当前授权人的信息,unionId参数必须传meGetUserResponseBodyres=client.getUserWithOptions("me", getUserHeaders, newRuntimeOptions()).getBody();
returnres;
    }
privateStringsaveSysUserAuto(OapiV2UserGetResponse.UserGetResponseuser) {
List<UserRole>userRoleList=newArrayList();
//整理需要插入数据库字段Stringuserid=user.getUserid();
//判断当前用户是否已经插入过了LonguserId=null;
SysUsersysUser=sysUserService.selectUserByDingDingUserid(userid);
if (sysUser!=null) {
userId=sysUser.getUserId();
        }else {
sysUser=newSysUser();
sysUser.setDingdingUserid(userid);
sysUser.setAvatar(user.getAvatar());
sysUser.setUnionId(user.getUnionid());
sysUser.setPhonenumber(user.getMobile());
sysUser.setEmail(user.getEmail());
sysUser.setTitle(user.getTitle());
StringuserName=user.getName();
sysUser.setUserName(userName);
//中文转拼音作为loginNameStringloginName=PinYinUtils.getPingYin(userName);
//根据当前公司人员重名情况,最大重名6人,故此处设置最大重名为10StringBuildersb=newStringBuilder(loginName).append(",");
for (inti=1; i<10; i++) {
sb.append(loginName+String.valueOf(i)).append(",");
            }
Stringloginnames=sb.toString();
//判断一下当前是否已经存在了loginnameSysUseruniqueuser=sysUserService.selectLastUserByLoginName(Convert.toStrArray(loginnames));
if (uniqueuser!=null) {
//获取当前重名用户的序号Stringnumber=uniqueuser.getLoginName().replace(loginName, "");
//序号增加1在放回去拼接好inti=0;
if (StringUtils.isNotEmpty(number)) {
i=Integer.parseInt(number) +1;
                }else {
//说明当前loginname还没有后续数字i=1;
                }
sysUser.setLoginName(loginName+i);
            }else {
sysUser.setLoginName(loginName);
            }
sysUser.randomSalt();
//初始未编码前password为123456sysUser.setPassword(passwordService.encryptPassword(sysUser.getLoginName(), "123456", sysUser.getSalt()));
sysUser.setCreateBy("扫码登录补充用户");
sysUser.setCreateTime(newDate());
sysUserService.insertSysUser(sysUser);
userId=sysUser.getUserId();
//插入用户的角色,初始用户都是普通角色UserRoleur=newUserRole();
ur.setUserId(userId);
if (Constants.ONE_KEY.equals(user.getUserid()) ||Constants.TWO_KEY.equals(user.getUserid())) {
ur.setRoleId(1L);
            }else {
ur.setRoleId(2L);
            }
userRoleList.add(ur);
        }
//插入用户的部门List<Long>deptIdList=user.getDeptIdList();
if (CollectionUtils.isNotEmpty(deptIdList)) {
//插入部门之前需要清除之前的人员部门关系,以防钉钉部门变动而系统未感知intdele=sysUserDeptService.deleteSysUserDeptByUserId(userId);
//插入人员部门关系表SysUserDeptuserDept=newSysUserDept();
userDept.setUserId(userId);
for (Longdeptid : deptIdList) {
userDept.setDeptId(deptid);
userDept.setCreateBy("扫码登录补充用户");
userDept.setCreateTime(newDate());
sysUserDeptService.insertSysUserDept(userDept);
            }
        }
//插入角色if (CollectionUtils.isNotEmpty(userRoleList)) {
userRoleMapper.batchUserRole(userRoleList);
        }
//登录系统returndoLoginSystem(sysUser);
    }


其中dingDingService.getUserIdByUnionIdV2(unionId)方法如下

/*** 根据unionId获取userId 2.0版本* @param unionId 当前钉钉用户在当前企业下的唯一识别码* @return*/@OverridepublicOapiUserGetbyunionidResponse.UserGetByUnionIdResponsegetUserIdByUnionIdV2(StringunionId) {
try {
StringaccessToken=getAccessToken();
//根据unionId获取userIdDingTalkClientclient=newDefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/getbyunionid");
OapiUserGetbyunionidRequestreq=newOapiUserGetbyunionidRequest();
req.setUnionid(unionId);
OapiUserGetbyunionidResponsersp=client.execute(req, accessToken);
OapiUserGetbyunionidResponse.UserGetByUnionIdResponseresult=rsp.getResult();
returnresult;
        } catch (ApiExceptione) {
e.printStackTrace();
        }
returnnull;
    }


dingDingService.getUserDetailByUserid(userIdByUnionIdV2.getUserid(), null)方法如下

/*** 查询用户详情* @param userid 钉钉userid* @param accessToken* @return*/@OverridepublicOapiV2UserGetResponse.UserGetResponsegetUserDetailByUserid(Stringuserid, StringaccessToken) {
try {
if (StringUtils.isEmpty(accessToken)) {
accessToken=getAccessToken();
            }
DingTalkClientclient=newDefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
OapiV2UserGetRequestreq=newOapiV2UserGetRequest();
req.setUserid(userid);
OapiV2UserGetResponsersp=client.execute(req, accessToken);
OapiV2UserGetResponse.UserGetResponseresult=rsp.getResult();
returnresult;
        } catch (ApiExceptione) {
e.printStackTrace();
returnnull;
        }
    }


PinYinUtils.java类如下

packagecom.dongao.project.utils;
importnet.sourceforge.pinyin4j.PinyinHelper;
importnet.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
importnet.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
importnet.sourceforge.pinyin4j.format.HanyuPinyinToneType;
importnet.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
importnet.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
/*** @ClassName:PinYinUtils* @author:dongao* @date 2022/2/10 14:05*/publicclassPinYinUtils {
/*** 中文转拼音* @param inputStr* @return*/publicstaticStringgetPingYin(StringinputStr) {
if (inputStr==null||"".equals(inputStr)) {
return"";
        }
HanyuPinyinOutputFormatformat=newHanyuPinyinOutputFormat();
//UPPERCASE 大写 LOWERCASE 小写format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
//WITH_TONE_NUMBER 音标用数字 WITHOUT_TONE 无音标 WITH_TONE_MARK 直接用音标format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
//WITH_U_AND_COLON 用u表示ü WITH_V 用v表示ü WITH_U_UNICODE 用ü表示üformat.setVCharType(HanyuPinyinVCharType.WITH_V);
StringBuilderpYStr=newStringBuilder();
char[] input=inputStr.trim().toCharArray();
try {
for (inti=0; i<input.length; i++) {
if (Character.toString(input[i]).matches("[\\u4E00-\\u9FA5]+")) {
pYStr.append(PinyinHelper.toHanyuPinyinStringArray(input[i], format)[0]);
                } elseif (!(input[i] ==' ')) {
//过滤空格pYStr.append(input[i]);
                }
            }
        } catch (BadHanyuPinyinOutputFormatCombinatione) {
e.printStackTrace();
        }
returnpYStr.toString();
    }
}


pom.xml增加

pom.xml涉及到的jar包有

<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.6</version></dependency><dependency><groupId>com.aliyun</groupId><artifactId>dingtalk</artifactId><version>1.1.86</version></dependency><dependency><groupId>com.aliyun</groupId><artifactId>alibaba-dingtalk-service-sdk</artifactId><version>2.0.0</version></dependency><dependency><groupId>com.belerweb</groupId><artifactId>pinyin4j</artifactId><version>2.5.0</version></dependency>


那么到这里整个关于钉钉一键授权登录的页面代码以及后台逻辑代码也就写完了,下面看一下一键登录的效果

一键登录效果展示

登录页面点击【钉钉一键授权登录】

image.png

跳转到钉钉授权页面

image.png

点击【立即登录】

image.png

跳转到系统首页,这里文中的图片打码主要是由于内容涉及不方便展示,希望可以谅解,整体的流程和代码是可以参考的,如果有问题欢迎大家评论区留言讨论。

相关文章
|
5月前
|
Java
钉钉第三方扫码登录提示 code: 403, 没有调用该接口的权限,接口权限申请参考
钉钉第三方扫码登录提示 code: 403, 没有调用该接口的权限,接口权限申请参考 ,但是我明明申请了Contact.User.Read 这个权限
197 1
|
7月前
|
移动开发 测试技术 开发工具
【钉钉免登录】(详解)钉钉接口,H5微应用,钉钉免登录及获取当前用户信息
【钉钉免登录】(详解)钉钉接口,H5微应用,钉钉免登录及获取当前用户信息
343 1
【钉钉免登录】(详解)钉钉接口,H5微应用,钉钉免登录及获取当前用户信息
|
6月前
|
移动开发 算法 编译器
OAUTH之 钉钉第三方授权登录
OAUTH之 钉钉第三方授权登录
315 0
|
6月前
|
存储 开发者
钉钉企业内部应用与第三方企业应用的主要区别
钉钉企业内部应用与第三方企业应用的主要区别
156 1
|
9月前
|
缓存 搜索推荐 网络安全
钉钉登录页面网页自动跳转,显示对不起,你无权限查看该页面,需要使用钉钉账号登录才可以进行授权
钉钉登录页面网页自动跳转,显示对不起,你无权限查看该页面,需要使用钉钉账号登录才可以进行授权
2553 1
|
10月前
|
移动开发 算法 编译器
OAUTH之钉钉第三方授权 | GO主题月
hello,我是小魔童哪吒,欢迎点击关注,有更新,将第一时间呈现到你的面前 胖sir:小魔童,我今天收到了一个需求,期望我们做一个第三方登录的功能,用户可以通过第三方授权来登录我们的web
263 0
|
存储 弹性计算 安全
成功案例-钉钉 | 学习笔记
快速学习 成功案例-钉钉
300 0
|
存储 弹性计算 安全
案例分享——钉钉|学习笔记
快速学习 案例分享——钉钉
279 0
|
移动开发 物联网 Go
SAP Business ByDesign 和支付宝与钉钉集成的一个原型开发案例
SAP Business ByDesign 和支付宝与钉钉集成的一个原型开发案例
SAP Business ByDesign 和支付宝与钉钉集成的一个原型开发案例
|
移动开发 物联网 智能硬件
SAP Business ByDesign 和支付宝与钉钉集成的一个原型开发案例
SAP Business ByDesign 和支付宝与钉钉集成的一个原型开发案例
189 0
SAP Business ByDesign 和支付宝与钉钉集成的一个原型开发案例

热门文章

最新文章