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

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

获取appId及appSecret

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

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

项目应用

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

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

2.下载sdk

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

3.将sdk引入项目

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

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


pom.xml引入sdk jar包

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

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

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

4.登录页修改

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


基于springboot架构 钉钉扫码登录第三方应用_加载_07


基于springboot架构 钉钉扫码登录第三方应用_加载_08


基于springboot架构 钉钉扫码登录第三方应用_加载_09


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

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