当前位置: 首页 > news >正文

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

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;
}

相关文章:

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

1&#xff1a;准备工作 1.1&#xff1a;进入钉钉开放平台创建开发者应用。应用创建和类型介绍&#xff0c;参考下方。 应用类型介绍 - 钉钉开放平台 (dingtalk.com) 应用能力介绍 - 钉钉开放平台 (dingtalk.com) 扫码登录第三方网站 - 钉钉开放平台 (dingtalk.com) 1.2&…...

二叉树构建(从3种遍历中构建)python刷题记录

R3-树与二叉树篇. 目录 从前序与中序遍历序列构造二叉树 算法思路&#xff1a; 灵神套路 从中序与后序遍历序列构造二叉树 算法思路&#xff1a; 灵神套路 从前序和后序遍历序列构造二叉树 算法思路&#xff1a; 灵神套路 从前序与中序遍历序列构造二叉树 算法…...

计算机网络中协议与报文的关系

协议和报文在网络通信中扮演着不同的角色&#xff0c;但它们是紧密相关的。 协议是计算机网络中实现通信的“约定”&#xff0c;它规定了计算机之间如何进行通信&#xff0c;包括数据传输的格式、步骤和规则。协议确保了不同厂商的设备、不同的CPU和操作系统之间的计算机能够相…...

机器学习 第8章-集成学习

机器学习 第8章-集成学习 8.1 个体与集成 集成学习(ensemble learning)通过构建并结合多个学习器来完成学习任务&#xff0c;有时也被称为多分类器系统(multi-classifersystem)、基于委员会的学习(committee-based learning)等。 图8.1显示出集成学习的一般结构:先产生一组“…...

Docker 安装 GitLab教程

本章教程,主要介绍如何在Docker 中安装GitLab。 GitLab 是一个开源的 DevOps 平台,提供了一整套工具,用于软件开发生命周期的各个阶段,从代码管理到 CI/CD(持续集成和持续交付/部署),再到监控和安全分析。 一、拉取镜像 docker pull gitlab/gitlab-ce:latest二、创建 G…...

如何在生产环境中千万表添加索引并保证数据一致性

技术分享文档&#xff1a;如何在生产环境中千万表添加索引并保证数据一致性 目录 引言添加索引的挑战解决方案概述详细步骤 4.1 创建新表并添加索引 4.2 批量导入数据 4.3 处理增量数据 4.4 表名切换确保数据一致性 5.1 暂停写操作 5.2 记录增量数据 5.3 应用增量数据设置回滚…...

Uni-APP页面跳转问题(十六)

【背景】最近在做公司一个PAD端,谁被点检功能,主要时为了移动端点检设备和打印标签,需求比较简单就是扫描设备二维码,问题在于扫描后要能够重复进行多设备的扫描;早期开发的设备点检能够满足需求但是当连续扫描五六十个设备后,APP卡死,必须重启才能使用。 界面原图: 输…...

Java新特性(二) Stream与Optional详解

Java8新特性&#xff08;二&#xff09; Stream与Optional详解 一. Stream流 1. Stream概述 1.1 基本概念 Stream&#xff08;java.util.stream&#xff09; 是Java 8中新增的一种抽象流式接口&#xff0c;主要用于配合Lambda表达式提高批量数据的计算和处理效率。Stream不是…...

springboot系列教程(三十一):springboot整合Nacos组件,环境搭建和入门案例详解

一、Nacos基础简介 1、概念简介 Nacos 是构建以“服务”为中心的现代应用架构&#xff0c;如微服务范式、云原生范式等服务基础设施。聚焦于发现、配置和管理微服务。Nacos提供一组简单易用的特性集&#xff0c;帮助开发者快速实现动态服务发现、服务配置、服务元数据及流量管…...

Traefik系列

一、入门Traefik系列——基础简介 官方文档 https://doc.traefik.io/traefik/[1] 简介 Traefik是一个为了让部署微服务更加便捷而诞生的现代HTTP反向代理、负载均衡工具。它支持多种后台 (Docker, Swarm, Kubernetes, Marathon, Mesos, Consul, Etcd, Zookeeper, BoltDB, Re…...

【力扣】3128. 直角三角形 JAVA

一、题目描述 给你一个二维 boolean 矩阵 grid 。 请你返回使用 grid 中的 3 个元素可以构建的 直角三角形 数目&#xff0c;且满足 3 个元素值 都 为 1 。 注意&#xff1a; 如果 grid 中 3 个元素满足&#xff1a;一个元素与另一个元素在 同一行&#xff0c;同时与第三个元素…...

如何全面提升企业安全意识

引言 在当今数字化和信息化的时代&#xff0c;网络安全已成为企业运营不可忽视的核心问题。员工的安全意识直接关系到企业的数据安全和整体网络防护能力。即使企业采用了先进的安全技术&#xff0c;如果员工缺乏足够的安全意识&#xff0c;仍然容易成为攻击者的突破口。本文将…...

全球支持与无界服务:跨越地域的数据采集与分析

在当今企业运营中&#xff0c;IT 监控系统的全球支持和无界服务变得至关重要。随着企业业务的全球化扩展&#xff0c;传统的监控工具往往因地域限制而无法满足全球统一监控的需求。观测云通过其全球部署的数据采集点和多语言支持&#xff0c;确保了无论数据产生于何处&#xff…...

Java面试八股之简述spring boot的目录结构

简述spring boot的目录结构 Spring Boot 项目遵循标准的 Maven 或 Gradle 项目布局&#xff0c;并且有一些约定的目录用于组织不同的项目组件。下面是一个典型的 Spring Boot 项目目录结构&#xff1a; src/main/java&#xff1a;包含所有的 Java 源代码&#xff0c;通常按包组…...

python == 与 is区别

刷到一个面试题 python中 与 is 的区别 根据以往的经验&#xff0c;这个问题应该考察的是运算符根据地址 还是值进行比较的 s1 [a] s2 [a] s3 s1 print(s1 s2) # True 值相等 print(s1 s3) # True 值相等 print(s1 is s2) # False 值相等&#xff0c;引用地址不相…...

STM32学习笔记1---LED,蜂鸣器

目录 GPIO LED 蜂鸣器 RCC外设 GPIO外设 总概 操作STM32的GPIO 代码 LED闪烁 LED流水灯 蜂鸣器&#xff01; 连接方式 GPIO GPIO输出&#xff1a;向外驱动控制 GPIO输入&#xff1a;读取&#xff0c;捕获&#xff08;信息&#xff09;&#xff08;控制&#xff09…...

动手学强化学习 第 15 章 模仿学习 训练代码

基于 https://github.com/boyu-ai/Hands-on-RL/blob/main/%E7%AC%AC15%E7%AB%A0-%E6%A8%A1%E4%BB%BF%E5%AD%A6%E4%B9%A0.ipynb 理论 模仿学习 修改了警告和报错 运行环境 Debian GNU/Linux 12 Python 3.9.19 torch 2.0.1 gym 0.26.2 运行代码 #!/usr/bin/env pythonimpor…...

第一阶段面试问题(前半部分)

1. 进程和线程的概念、区别以及什么时候用线程、什么时候用进程&#xff1f; &#xff08;1&#xff09;线程 线程是CPU任务调度的最小单元、是一个轻量级的进程 &#xff08;2&#xff09;进程 进程是操作系统资源分配的最小单元 进程是一个程序动态执行的过程&#xff0c;包…...

《数学教学通讯》是一本怎样的刊物?投稿难吗?

《数学教学通讯》是一本怎样的刊物&#xff1f;投稿难吗&#xff1f; 《数学教学通讯》是一本具有较高学术价值的教育类刊物。它创刊于 1979 年&#xff0c;由西南大学主管&#xff0c;西南大学数学与统计学院、重庆市数学学会主办&#xff0c;出版周期为旬刊。该刊物在国内外…...

<机器学习> K-means

K-means定义 K-means 是一种广泛使用的聚类算法&#xff0c;旨在将数据集中的点分组为 K 个簇&#xff08;cluster&#xff09;&#xff0c;使得每个簇内的点尽可能相似&#xff0c;而不同簇的点尽可能不同。K-means 算法通过迭代的方式&#xff0c;逐步优化簇的分配和簇的中心…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...