spring boot + vue3 接入钉钉实现扫码登录

news/2024/9/23 21:15:25/

1:准备工作

        1.1:进入钉钉开放平台创建开发者应用。应用创建和类型介绍,参考下方。

应用类型介绍 - 钉钉开放平台 (dingtalk.com)

应用能力介绍 - 钉钉开放平台 (dingtalk.com)

扫码登录第三方网站 - 钉钉开放平台 (dingtalk.com)

        1.2:创建好的应用,给对应权限。

      我开通了个人权限和通讯录管理所有权限,建议是全部员工,因为这个权限只能api的权限,不会影响钉钉的权限

   

2:扫码登录具体实现和效果

2.1 前端和后端代码展示(前端不是很会)

工作流程介绍

用户扫码-->授权之后重定向给钉钉处理返回一个code--->钉钉处理之后执行回调域名并且携带code-->调用getBycodeResponse接口返回unionid --> 然后调用scanCodeLogin 登录接口---->成功之后进入首页。

先在 index.html 内引入一段脚本:
<script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script>
再编写如下代码:
const redirect_uri = 'http://192.168.0.137:3000/#/ddlogin';
onMounted(()=>{
const url = encodeURIComponent(redirect_uri);
const goto = encodeURIComponent('https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=%E4%BD%A0%E7%9A%84APP_ID&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=icon-default.png?t=N7T8https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=%E4%BD%A0%E7%9A%84APP_ID&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=' + url);
const obj = window.DDLogin({
id:"ddLogin",
goto,
style: "border: none",
width : "350",
height: "350"
});
});
const handleMessage = function (event: any) {
const origin = event.origin;
if( origin == "https://login.dingtalk.com" ) { //判断是否来自ddLogin扫码事件。
// 下面这个连接会在钉钉那边处理完毕之后直接让浏览器的URL变成 redirect_uri
location.href = 'https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=%E4%BD%A0%E7%9A%84APP_ID&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=icon-default.png?t=N7T8https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=%E4%BD%A0%E7%9A%84APP_ID&response_type=code&scope=snsapi_login&state=STATE&redirect_uri='+ encodeURIComponent(redirect_uri) + '&loginTmpCode=' + event.data;
}
};收起链接预览无权限https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=dingtalk.com无权限https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=dingtalk.com

@ApiOperation(value = "根据sns临时授权码获取用户信息", notes = "根据sns临时授权码获取用户信息")
@RequestMapping(value = "/getBycodeResponse", method = RequestMethod.GET)
public OapiSnsGetuserinfoBycodeResponse getBycodeResponse(@RequestParam(value = "authCode")String authCode) throws JsonProcessingException, ApiException {OapiSnsGetuserinfoBycodeResponse bycodeResponse = sampleUtlis.getBycodeResponse(authCode, AppKey, appSecret);return  bycodeResponse;}

/*** 退出登录* @return*/
@ApiOperation(value = "扫码登录验证", notes = "扫码登录验证")
@GetMapping(value = "/scanCodeLogin")
public Result<Object> scanCodeLogin(@RequestParam("unionid") String unionid, HttpServletResponse response) {Result<Object>  result=new Result<>();try {ZuodouUser zuodouUser = zuodouUserMapper.selectOne(new LambdaQueryWrapper<ZuodouUser>().eq(StringUtils.isNotBlank(unionid), ZuodouUser::getUnionid, unionid));if (null==zuodouUser){result.error500("查无此人");return result;}String username = zuodouUser.getUsername();//判断用户是否存在ZuodouUser  bannerItem=zuodouUserMapper.selectOne(new LambdaQueryWrapper<ZuodouUser>().eq(ZuodouUser::getUsername,username));result =iZuodouUserService.verifyaccount(bannerItem);if(!result.isSuccess()) {return result;}UserModel userModel=new UserModel();BeanUtils.copyProperties(bannerItem,userModel);List<ZuodouUserRole> zuodouUserRoles = zuodouUserRoleService.list(new LambdaQueryWrapper<ZuodouUserRole>().eq(ZuodouUserRole::getUserId, bannerItem.getId()).eq(ZuodouUserRole::getStatus, StatusEum.getNameValue(CommonConstant.STATUSNAME_A)));if (!CollectionUtils.isEmpty(zuodouUserRoles)){userModel.setRole(zuodouUserRoles.stream().map(s->s.getRoleId()).collect(Collectors.toList()));List<String> zuodouRolePermissions = zuodouRolePermissionMapper.listPermission(userModel.getRole());if (!CollectionUtils.isEmpty(zuodouRolePermissions)){userModel.setPermission(zuodouRolePermissions);}}zuodouUser.setLastLogin(new Date());zuodouUserMapper.updateById(zuodouUser);String jwtToken = JwtUtils.getJwtToken(userModel);Cookie cookie = new Cookie(userTokenUtils.getTokenCode(), jwtToken);cookie.setPath("/");cookie.setMaxAge(Math.toIntExact(CommonConstant.TOKEN_EXPIRE));response.addCookie(cookie);//先删除keyredisUtil.del(userTokenUtils.getTokenCode()+bannerItem.getId());redisUtil.set(userTokenUtils.getTokenCode() + bannerItem.getId(), jwtToken,CommonConstant.REDIS_EXPIRE*2);log.info(userTokenUtils.getTokenCode() + bannerItem.getId());Map<String,Object> map=new HashMap<>();map.put(CommonConstant.TOKEN_MODEL,bannerItem);map.put(userTokenUtils.getTokenCode(),jwtToken);result.setResult(map);result.success("登录成功");} catch (Exception e) {e.printStackTrace();result.error500("操作失败");}return result;
}

http://www.ppmy.cn/news/1503963.html

相关文章

全开源TikTok跨境商城源码/TikTok内嵌商城+搭建教程/前端uniapp+后端

多语言跨境电商外贸商城 TikTok内嵌商城&#xff0c;商家入驻一键铺货一键提货 全开源完美运营 海外版抖音TikTok商城系统源码&#xff0c;TikToK内嵌商城&#xff0c;跨境商城系统源码 接在tiktok里面的商城。tiktok内嵌&#xff0c;也可单独分开出来当独立站运营 二十一种…

Unity-Redis数据存储

1.Redis 安装测试&#xff1a;   安装&#xff1a;     安装包 链接&#xff1a;https://pan.baidu.com/s/1BzuqRNJHW1MiB4xm4UT4MA 提取码&#xff1a;pvrj   使用:     运行包内 redis-server.exe 启动 Redis 服务 &#xff0c;运行包内 redis-cli.exe 启动客户端…

在单片机上实现Ymodem协议接收文件的实现

目录 1. Y-Modem协议介绍 1.1 Y-Modem协议简介 1.2 Y-Modem协议格式 1.2.1 Y-Modem起始帧 1.2.2 Y-Modem数据帧 1.2.3 Y-Modem结束帧 1.2.4 Y-Modem命令 2. Tera Term软件使用 2.1 Tera Term软件的使用 3. 单片机接收端实现代码 本篇文章主要介绍的是通过Y-Modem协议如…

MyBatis开发: XML配置⽂件

前言 在IDEA的yml文件注释发现乱码 1.配置文件注释中文显示乱码 退出重进&#xff0c;发现不是乱码就成功 一.MyBatis XML配置⽂件 学习了注解的⽅式, 接下来我们学习XML的⽅式. 使⽤Mybatis的注解⽅式&#xff0c;主要是来完成⼀些简单的增删改查功能. 如果需要实现复杂的SQL…

微前端(qiankun)

微前端 特点&#xff1a;独立开发、独立部署&#xff0c;独立运行&#xff0c;增量升级 解决的问题&#xff1a;日常开发过程中&#xff0c;可能有很多老项目需要迭代&#xff0c;但是可能新的一些可能需要使用的依赖或者新的一些框架&#xff0c;老项目已经不满足&#xff0c;…

FFmpeg实现文件夹多视频合并

ffmpeg version 6.1.1 要求: 合并的视频同分辨率、同帧率 命令: python 多文件夹多视频合并.py --input_videos D:\videos --output_videos D:\out_videos --output_txts D:\out_txt要求视频文件夹输入目录:--videos--test1001.mp4002.mp4--test2001.mp4002.mp4输出目录(自动创…

Python酷库之旅-第三方库Pandas(034)

目录 一、用法精讲 101、pandas.Series.__array__魔法方法 101-1、语法 101-2、参数 101-3、功能 101-4、返回值 101-5、说明 101-6、用法 101-6-1、数据准备 101-6-2、代码示例 101-6-3、结果输出 102、pandas.Series.get方法 102-1、语法 102-2、参数 102-3、…

TCP为什么需要四次挥手?

tcp为什么需要四次挥手&#xff1f; 答案有两个&#xff1a; 1.将发送fin包的权限交给被动断开方的应用层去处理&#xff0c;也就是让程序员处理 2.接第一个答案&#xff0c;应用层有了发送fin的权限&#xff0c;可以在发送fin前继续向对端发送消息 为了搞清楚这个问题&…