基于springboot架构 钉钉扫码登录第三方应用
获取appId及appSecret
点击进入钉钉开发者平台 的页面,点击左侧菜单的【移动接入应用-登录】,然后点击右上角的【创建扫码登录应用授权】,创建用于免登过程中验证身份的appId及appSecret,创建后即可看到appId和appSecret。
项目应用
1.配置文件增加如下配置
2.下载sdk
下载地址: https://ding-doc.dingtalk.com/doc#/faquestions/vzbp02
3.将sdk引入项目
在resources下创建lib文件夹,放入下载的sdk
pom.xml引入sdk jar包
3.修改登录跳转方法/login
4.登录页修改
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+"×tamp="+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(); } }
以上为整合钉钉扫码的主要代码,并不是全部代码,仅供参考