基于springboot架构 钉钉扫码登录第三方应用

简介: • 获取appId及appSecret• 项目应用• 1.配置文件增加如下配置• 2.下载sdk• 3.将sdk引入项目• 3.修改登录跳转方法/login• 4.登录页修改• 5.扫码重定向实现登录的方法如下• 6.重写UsernamePasswordToken


基于springboot架构 钉钉扫码登录第三方应用


获取appId及appSecret

点击进入钉钉开发者平台 的页面,点击左侧菜单的【移动接入应用-登录】,然后点击右上角的【创建扫码登录应用授权】,创建用于免登过程中验证身份的appId及appSecret,创建后即可看到appId和appSecret。

image.png


项目应用

1.配置文件增加如下配置

image.png


2.下载sdk

下载地址: https://ding-doc.dingtalk.com/doc#/faquestions/vzbp02


3.将sdk引入项目

在resources下创建lib文件夹,放入下载的sdk

image.png


pom.xml引入sdk jar包

image.png


3.修改登录跳转方法/login

image.png


4.登录页修改

image.png

image.png

image.png

image.png


dingding.css文件

#background { position:fixed;left:0px;top:0px;
    background-color:black;
    width:100%;
    height:100%;
    opacity:0.5;
    display:none;
    z-Index:3;
}
#content { position:fixed;
    width:420px;
    height:420px;
    top:0;
    bottom:0;
    left:0;
    right:0;
    margin:auto;
    display:none;
    cursor:pointer;
    z-Index:3;
}
#close {
    float: right;
    margin-right: 50px;
    display: block;
    width: 32px;
    height: 32px;
    background: url(../img/close.png) no-repeat 0px 0px;
}



dingding.js文件

//钉钉扫码登录
function show()  //显示隐藏层和弹出层
{
    var background=document.getElementById("background");
    background.style.display="block";  //显示隐藏层
    document.getElementById("content").style.display="block";  //显示弹出层
    //此处不采用初始加载办法,根据需要加载,提高加载速度
    var appId = $("#appId").val();
    var projectUrl = $("#projectUrl").val();
    /*
     * 解释一下goto参数,参考以下例子:
     * var url = encodeURIComponent('http://localhost.me/index.php?test=1&aa=2');
     * var goto = encodeURIComponent('https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=appid&response_type=code&scope=snsapi_login&state=STATE&redirect_uri='+url)
     */
    var redirectUrl = projectUrl+'loginSys';
    var goto = encodeURIComponent('https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid='+appId+'&response_type=code&scope=snsapi_login&state=STATE&redirect_uri='+redirectUrl);
    var obj = DDLogin({
        id:"login_container",//这里需要你在自己的页面定义一个HTML标签并设置id,例如<div id="login_container"></div>或<span id="login_container"></span>
        goto: goto, //请参考注释里的方式
        style: "border:none;background-color:#FFFFFF;",
        width : "365",
        height: "400"
    });
    var handleMessage = function (event) {
        var origin = event.origin;
        //console.log("origin", event.origin);
        if( origin == "https://login.dingtalk.com" ) { //判断是否来自ddLogin扫码事件。
            var loginTmpCode = event.data; //拿到loginTmpCode后就可以在这里构造跳转链接进行跳转了
            //console.log("loginTmpCode", loginTmpCode);
            window.location.href = 'https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid='+appId+'&response_type=code&scope=snsapi_login&state=STATE&redirect_uri='+redirectUrl+'&loginTmpCode='+ loginTmpCode;
        }
    };
    if (typeof window.addEventListener != 'undefined') {
        window.addEventListener('message', handleMessage, false);
    } else if (typeof window.attachEvent != 'undefined') {
        window.attachEvent('onmessage', handleMessage);
    }
}
function hide()  //去除隐藏层和弹出层
{
    document.getElementById("background").style.display="none";
    document.getElementById("content").style.display="none";
}


5.扫码重定向实现登录的方法如下

    /**
     * 扫码登录并跳转到index
     * @param request
     * @return
     */
    @RequestMapping("/loginSys")
    public String loginSys(HttpServletRequest request)
    {
        String code = request.getParameter("code");
        //String state = request.getParameter("state");
        String appId = ConstantConfig.dingtalkAppId;
        String appSecret = ConstantConfig.dingtalkAppSecret;
        String msg = "";
        //扫码登录
        try {
            //获取签名值
            String timestamp = String.valueOf(System.currentTimeMillis());
            String urlEncodeSignature = DingDingUtil.urlEncodeSignature(timestamp,appSecret);
            //获取unionId
            String url = ConstantConfig.dingtalkUserInfoUrl+"?accessKey="+appId+"&timestamp="+timestamp+"&signature="+urlEncodeSignature;
            DefaultDingTalkClient client = new DefaultDingTalkClient(url);
            OapiSnsGetuserinfoBycodeRequest req = new OapiSnsGetuserinfoBycodeRequest();
            req.setTmpAuthCode(code);
            OapiSnsGetuserinfoBycodeResponse response = client.execute(req,appId,appSecret);
            OapiSnsGetuserinfoBycodeResponse.UserInfo userInfo = response.getUserInfo();
            String unionId = userInfo.getUnionid();
            User use = sysService.selectUserByUnionId(unionId);
            //根据unionId 获取用户信息
            if (use != null && StringUtils.isNotEmpty(use.getUnionId())) {
                //已绑定账号则直接登录操作
                MyUsernamePasswordToken token = new MyUsernamePasswordToken(use.getLoginName(), use.getPassword(),false,true);
                Subject subject = SecurityUtils.getSubject();
                subject.login(token);
                return redirect("/index");
            }else {
                //未绑定
                msg = "one";
            }
        } catch (Exception e) {
            e.printStackTrace();
            msg = "two";
        }
        return redirect("/login?msg="+msg);
    }


6.重写UsernamePasswordToken

package com.ruoyi.framework.shiro.authc;
import org.apache.shiro.authc.UsernamePasswordToken;
/**
 * Created by nao'nao on 2020/3/19.
 * @author
 */
public class MyUsernamePasswordToken extends UsernamePasswordToken {
    private String username;
    private char[] password;
    private boolean rememberMe;
    private String host;
    private boolean encryption;
    private String passwords;
    public MyUsernamePasswordToken() {
        this.rememberMe = false;
        this.encryption = false;
    }
    public MyUsernamePasswordToken(String username, char[] password) {
        this(username, (char[])password, false, (String)null, false);
    }
    public MyUsernamePasswordToken(String username, String password) {
        this(username, (char[])(password != null?password.toCharArray():null), false, (String)null, false);
    }
    public MyUsernamePasswordToken(String username, char[] password, String host) {
        this(username, password, false, host, false);
    }
    public MyUsernamePasswordToken(String username, String password, String host) {
        this(username, password != null?password.toCharArray():null, false, host, false);
    }
    public MyUsernamePasswordToken(String username, char[] password, boolean rememberMe) {
        this(username, (char[])password, rememberMe, (String)null, false);
    }
    public MyUsernamePasswordToken(String username, String password, boolean rememberMe) {
        this(username, (char[])(password != null?password.toCharArray():null), rememberMe, (String)null,false);
    }
    public MyUsernamePasswordToken(String username, String password, boolean rememberMe, String host) {
        this(username, password != null?password.toCharArray():null, rememberMe, host,false);
    }
    public MyUsernamePasswordToken(String username, String passwords, boolean rememberMe, boolean encryption) {
        this(username, passwords, rememberMe, (String)null, encryption);
    }
    public MyUsernamePasswordToken(String username, char[] password, boolean rememberMe, String host, boolean encryption) {
        this.rememberMe = false;
        this.encryption = false;
        this.username = username;
        this.password = password;
        this.rememberMe = rememberMe;
        this.host = host;
        this.encryption = encryption;
    }
    public MyUsernamePasswordToken(String username, String passwords, boolean rememberMe, String host, boolean encryption) {
        this.rememberMe = false;
        this.encryption = false;
        this.username = username;
        this.passwords = passwords;
        this.rememberMe = rememberMe;
        this.host = host;
        this.encryption = encryption;
    }
    @Override
    public String getUsername() {
        return username;
    }
    @Override
    public void setUsername(String username) {
        this.username = username;
    }
    @Override
    public char[] getPassword() {
        return password;
    }
    @Override
    public void setPassword(char[] password) {
        this.password = password;
    }
    @Override
    public boolean isRememberMe() {
        return rememberMe;
    }
    @Override
    public void setRememberMe(boolean rememberMe) {
        this.rememberMe = rememberMe;
    }
    @Override
    public String getHost() {
        return host;
    }
    @Override
    public void setHost(String host) {
        this.host = host;
    }
    public boolean isEncryption() {
        return encryption;
    }
    public void setEncryption(boolean encryption) {
        this.encryption = encryption;
    }
    public String getPasswords() {
        return passwords;
    }
    public void setPasswords(String passwords) {
        this.passwords = passwords;
    }
    @Override
    public Object getPrincipal() {
        return this.getUsername();
    }
    @Override
    public Object getCredentials() {
        if (this.isEncryption()) {
            return this.getPasswords();
        }else {
            return this.getPassword();
        }
    }
    @Override
    public void clear() {
        this.username = null;
        this.host = null;
        this.rememberMe = false;
        this.encryption = false;
        if(this.password != null) {
            for(int i = 0; i < this.password.length; ++i) {
                this.password[i] = 0;
            }
            this.password = null;
        }
        if (this.passwords != null) {
            this.passwords = null;
        }
    }
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(this.getClass().getName());
        sb.append(" - ");
        sb.append(this.username);
        sb.append(", rememberMe=").append(this.rememberMe);
        sb.append(", encryption=").append(this.encryption);
        if(this.host != null) {
            sb.append(" (").append(this.host).append(")");
        }
        return sb.toString();
    }
}

以上为整合钉钉扫码的主要代码,并不是全部代码,仅供参考


相关文章
|
7月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
1112 3
|
5月前
|
监控 Cloud Native Java
Spring Boot 3.x 微服务架构实战指南
🌟蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕Spring Boot 3.x与微服务架构,探索云原生、性能优化与高可用系统设计。以代码为笔,在二进制星河中谱写极客诗篇。关注我,共赴技术星辰大海!(238字)
1002 2
Spring Boot 3.x 微服务架构实战指南
|
5月前
|
人工智能 JavaScript 前端开发
GenSX (不一样的AI应用框架)架构学习指南
GenSX 是一个基于 TypeScript 的函数式 AI 工作流框架,以“函数组合替代图编排”为核心理念。它通过纯函数组件、自动追踪与断点恢复等特性,让开发者用自然代码构建可追溯、易测试的 LLM 应用。支持多模型集成与插件化扩展,兼具灵活性与工程化优势。
393 6
|
6月前
|
人工智能 Cloud Native 中间件
划重点|云栖大会「AI 原生应用架构论坛」看点梳理
本场论坛将系统性阐述 AI 原生应用架构的新范式、演进趋势与技术突破,并分享来自真实生产环境下的一线实践经验与思考。
|
6月前
|
Java 数据库 数据安全/隐私保护
Spring Boot四层架构深度解析
本文详解Spring Boot四层架构(Controller-Service-DAO-Database)的核心思想与实战应用,涵盖职责划分、代码结构、依赖注入、事务管理及常见问题解决方案,助力构建高内聚、低耦合的企业级应用。
1240 1
|
6月前
|
机器学习/深度学习 人工智能 vr&ar
H4H:面向AR/VR应用的NPU-CIM异构系统混合卷积-Transformer架构搜索——论文阅读
H4H是一种面向AR/VR应用的混合卷积-Transformer架构,基于NPU-CIM异构系统,通过神经架构搜索实现高效模型设计。该架构结合卷积神经网络(CNN)的局部特征提取与视觉Transformer(ViT)的全局信息处理能力,提升模型性能与效率。通过两阶段增量训练策略,缓解混合模型训练中的梯度冲突问题,并利用异构计算资源优化推理延迟与能耗。实验表明,H4H在相同准确率下显著降低延迟和功耗,为AR/VR设备上的边缘AI推理提供了高效解决方案。
967 0
|
5月前
|
机器学习/深度学习 自然语言处理 算法
48_动态架构模型:NAS在LLM中的应用
大型语言模型(LLM)在自然语言处理领域的突破性进展,很大程度上归功于其庞大的参数量和复杂的网络架构。然而,随着模型规模的不断增长,计算资源消耗、推理延迟和部署成本等问题日益凸显。如何在保持模型性能的同时,优化模型架构以提高效率,成为2025年大模型研究的核心方向之一。神经架构搜索(Neural Architecture Search, NAS)作为一种自动化的网络设计方法,正在为这一挑战提供创新性解决方案。本文将深入探讨NAS技术如何应用于LLM的架构优化,特别是在层数与维度调整方面的最新进展,并通过代码实现展示简单的NAS实验。
|
7月前
|
Web App开发 Linux 虚拟化
Omnissa Horizon 8 2506 (8.16) - 虚拟桌面基础架构 (VDI) 和应用软件
Omnissa Horizon 8 2506 (8.16) - 虚拟桌面基础架构 (VDI) 和应用软件
362 0
Omnissa Horizon 8 2506 (8.16) - 虚拟桌面基础架构 (VDI) 和应用软件
|
7月前
|
机器学习/深度学习 数据采集 存储
技术赋能下的能源智慧管理:MyEMS 开源系统的架构创新与应用深化
在全球能源转型与“双碳”战略推动下,MyEMS作为基于Python的开源能源管理系统,凭借模块化架构与AI技术,助力重点用能单位实现数字化、智能化能源管理。系统支持多源数据采集、智能分析、设备数字孪生与自适应优化控制,全面满足国家级能耗监测要求,并已在制造、数据中心、公共建筑等领域成功应用,助力节能降碳,推动绿色可持续发展。
209 0

热门文章

最新文章