springboot+vue (ruoyi-vue前后端分离)集成钉钉登录
1、钉钉开发者后台添加应用
登录钉钉开发者后台https://open-dev.dingtalk.com/,创建h5应用。
创建详情如下,保存并发布应用。
开通授权个人信息,添加使用的用户权限。这些在钉钉的文档中有详细步骤。
本地开发测试时,需要做内网穿透,我使用的frp的内网穿透。
2、代码集成justAuth插件
程序集成justAuth插件
https://github.com/justauth/JustAuth
<dependency><groupId>me.zhyd.oauth</groupId><artifactId>JustAuth</artifactId><version>{latest-version}</version>
</dependency><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.9.1</version>
</dependency>
3.前端
3.1、增加授权页面
创建一个第三方授权页面,用户向数据库中添加钉钉用户信息。
我将此页面集成在登录我方网站后的个人信息页面,其中authUrl方法会去后台请求一个路径,返回放入页面显示一个二维码,用户使用钉钉扫描后,会将用户信息写入一个表格中。
添加thirdParty.vue
<template><div><el-table :data="auths" style="width: 100%; height: 100%; font-size: 10px"><el-table-column label="序号" width="50" type="index"></el-table-column><el-table-columnlabel="绑定账号平台"width="140"align="center"prop="source":show-overflow-tooltip="true"/><el-table-column label="头像" width="120" align="center" prop="avatar"><template slot-scope="scope"><img :src="scope.row.avatar" style="width: 45px; height: 45px" /></template></el-table-column><el-table-columnlabel="系统账号"width="180"align="center"prop="userName":show-overflow-tooltip="true"/><el-table-columnlabel="绑定时间"width="180"align="center"prop="createTime"/><el-table-columnlabel="操作"width="80"align="center"class-name="small-padding fixed-width"><template slot-scope="scope"><el-buttonsize="mini"type="text"icon="el-icon-delete"@click="unlockAuth(scope.$index, scope.row)"></el-button></template></el-table-column></el-table><div id="git-user-binding"><h4 class="provider-desc">你可以绑定以下第三方帐号用于本系统</h4><div id="authlist" class="user-bind"><aclass="third-app"href="#"@click="authUrl('dingtalk');"title="使用 钉钉 账号授权登录"><div class="git-other-login-icon"><svg-icon icon-class="dingding" /></div><span class="app-name">钉钉</span></a><!-- <aclass="third-app"href="#"@click="authUrl('gitee');"title="使用 Gitee 账号授权登录"><div class="git-other-login-icon"><svg-icon icon-class="gitee" /></div><span class="app-name">Gitee</span></a><aclass="third-app"href="#"@click="authUrl('github');"title="使用 GitHub 账号授权登录"><div class="git-other-login-icon"><svg-icon icon-class="github" /></div><span class="app-name">Github</span></a><a class="third-app" href="#" title="功能开发中..."><div class="git-other-login-icon"><svg-icon icon-class="weixin" /></div><span class="app-name">WeiXin</span></a><a class="third-app" href="#" title="功能开发中..."><div class="git-other-login-icon"><svg-icon icon-class="qq" /></div><span class="app-name">QQ</span></a>--></div></div></div>
</template><script>
import { authUnlock, authBinding } from "@/api/system/auth";export default {props: {auths: {type: Array,},},data() {return {};},methods: {unlockAuth(index, row) {var _this = this;this.$modal.confirm('您确定要解除"' + row.source + '"的账号绑定吗?').then(function () {return authUnlock(row.authId);}).then(() => {_this.auths.splice(index, 1);this.$modal.msgSuccess("解绑成功");}).catch(() => {});},authUrl(source) {authBinding(source).then(res => {top.location.href = res.msg;});}},
};
</script><style type="text/css">
.user-bind .third-app {display: -webkit-box;display: -ms-flexbox;display: flex;-webkit-box-orient: vertical;-webkit-box-direction: normal;-ms-flex-direction: column;flex-direction: column;-webkit-box-align: center;-ms-flex-align: center;align-items: center;min-width: 80px;float: left;
}
.user-bind {font-size: 1rem;text-align: start;height: 50px;margin-top: 10px;
}
.git-other-login-icon > img {height: 32px;
}
a {text-decoration: none;cursor: pointer;color: #005980;
}
.provider-desc {font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial,"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Liberation Sans","PingFang SC", "Microsoft YaHei", "Hiragino Sans GB", "Wenquanyi Micro Hei","WenQuanYi Zen Hei", "ST Heiti", SimHei, SimSun, "WenQuanYi Zen Hei Sharp",sans-serif;font-size: 1.071rem;
}
td > img {height: 20px;width: 20px;display: inline-block;border-radius: 50%;margin-right: 5px;
}
</style>
3.2 添加 /src/api/system/auth.js
import request from '@/utils/request'// 绑定账号
export function authBinding(source) {return request({url: '/system/auth/binding/' + source,method: 'get'})
}// 解绑账号
export function authUnlock(authId) {return request({url: '/system/auth/unlock/' + authId,method: 'delete'})
}
3.3 login.vue登录界面增加第三方登录
<!-- 第三方应用登录 --><el-form-item style="width:100%;"><div class="oauth-login" style="display:flex"><div class="oauth-login-item" @click="doSocialLogin('dingtalk')"><svg-icon icon-class="dingding" style="width: 20px;height: 20px;" /><span style="color: #a19f9f; padding-left:3px;">钉钉</span></div></div></el-form-item>import { authBinding } from "@/api/system/auth";methods: {
doSocialLogin(source) {authBinding(source).then(res => {top.location.href = res.msg;});},
}<style rel="stylesheet/scss" lang="scss">.oauth-login {display: flex;align-items: cen;cursor:pointer;}.oauth-login-item {display: flex;align-items: center;margin-right: 10px;}.oauth-login-item img {height: 25px;width: 25px;}.oauth-login-item span:hover {text-decoration: underline red;color: red;}
</style>
3.4 /api/login.js
// 第三方平台登录
export function socialLogin(source, code, state) {const data = {code,state}return request({url: '/system/auth/social-login/' + source,method: 'get',params: data})
}
3.5 /src/utils/request.js
if (code === 10002) {// 第三方登录错误提示MessageBox.confirm(msg, '系统提示', {confirmButtonText: '重新登录',cancelButtonText: '取消',type: 'warning'}).then(() => {store.dispatch('LogOut').then(() => {location.href = '/index';})}).catch(() => {});return Promise.reject(new Error(msg))} else if (code === 500) {……
3.6 /src/store/modules/usr.js
import { login, socialLogin, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth'const user = {state: {token: getToken(),id: '',name: '',avatar: '',roles: [],permissions: []},mutations: {SET_TOKEN: (state, token) => {state.token = token},SET_ID: (state, id) => {state.id = id},SET_NAME: (state, name) => {state.name = name},SET_AVATAR: (state, avatar) => {state.avatar = avatar},SET_ROLES: (state, roles) => {state.roles = roles},SET_PERMISSIONS: (state, permissions) => {state.permissions = permissions}},actions: {// 登录Login({ commit }, userInfo) {const username = userInfo.username.trim()const password = userInfo.passwordconst code = userInfo.codeconst uuid = userInfo.uuidreturn new Promise((resolve, reject) => {login(username, password, code, uuid).then(res => {setToken(res.token)commit('SET_TOKEN', res.token)resolve()}).catch(error => {reject(error)})})},// 第三方平台登录SocialLogin({ commit }, userInfo) {const code = userInfo.codeconst state = userInfo.stateconst source = userInfo.sourcereturn new Promise((resolve, reject) => {socialLogin(source, code, state).then(res => {setToken(res.token)commit('SET_TOKEN', res.token)resolve()}).catch(error => {reject(error)})})},// 获取用户信息GetInfo({ commit, state }) {return new Promise((resolve, reject) => {getInfo().then(res => {const user = res.userconst avatar = (user.avatar == "" || user.avatar == null) ? require("@/assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar;if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组commit('SET_ROLES', res.roles)commit('SET_PERMISSIONS', res.permissions)} else {commit('SET_ROLES', ['ROLE_DEFAULT'])}commit('SET_ID', user.userId)commit('SET_NAME', user.userName)commit('SET_AVATAR', avatar)resolve(res)}).catch(error => {reject(error)})})},// 退出系统LogOut({ commit, state }) {return new Promise((resolve, reject) => {logout(state.token).then(() => {commit('SET_TOKEN', '')commit('SET_ROLES', [])commit('SET_PERMISSIONS', [])removeToken()resolve()}).catch(error => {reject(error)})})},// 前端 登出FedLogOut({ commit }) {return new Promise(resolve => {commit('SET_TOKEN', '')removeToken()resolve()})}}
}export default user
3.7 /src/permission.js
const whiteList = ['/login', '/social-login', '/bind','/register']; //加入白名单if (to.path === '/login') {……} else if (whiteList.indexOf(to.path) !== -1) { //加这里next()}
3.8 /src/router/index.js
……
{path: '/social-login',component: () => import('@/views/socialLogin'),hidden: true
},……// 防止连续点击多次路由报错
let routerPush = Router.prototype.push;
let routerReplace = Router.prototype.replace;
// push
Router.prototype.push = function push(location) {return routerPush.call(this, location).catch(err => err)
}
// replace
Router.prototype.replace = function push(location) {return routerReplace.call(this, location).catch(err => err)
}
3.9 增加页面socialLogin.vue
<template><div></div>
</template><script>
import { Loading } from 'element-ui'let loadingInstance;
export default {data() {return {redirect: undefined,};},created() {loadingInstance = Loading.service({lock: true,text: "正在验证第三方应用账户数据,请稍候",spinner: "el-icon-loading",background: "rgba(0, 0, 0, 0.7)",})// 第三方登录回调参数this.source = this.$route.query.source;this.code = this.$route.query.code;this.state = this.$route.query.state;this.$store.dispatch("SocialLogin", {code: this.code,state: this.state,source: this.source}).then(() => {loadingInstance.close();this.$router.push({ path: this.redirect || "/" }).catch(()=>{});}).catch(() => {loadingInstance.close();});},methods: {},
};
</script><style rel="stylesheet/scss" lang="scss">
</style>
4、后台添加第三方认证授权处理
4.1 新增认证授权处理 SysAuthController
package com.minhope.web.controller.system;import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;import com.minhope.system.service.ISysConfigService;
import com.minhope.system.service.ISysDictDataService;
import me.zhyd.oauth.request.AuthRequest;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson2.JSONObject;
import com.minhope.common.constant.Constants;
import com.minhope.common.core.controller.BaseController;
import com.minhope.common.core.domain.AjaxResult;
import com.minhope.common.core.domain.entity.SysUser;
import com.minhope.common.core.domain.model.LoginUser;
import com.minhope.common.enums.UserStatus;
import com.minhope.common.exception.ServiceException;
import com.minhope.common.utils.AuthUtils;
import com.minhope.common.utils.SecurityUtils;
import com.minhope.common.utils.StringUtils;
import com.minhope.framework.web.service.SysPermissionService;
import com.minhope.framework.web.service.TokenService;
import com.minhope.system.domain.SysAuthUser;
import com.minhope.system.mapper.SysUserMapper;
import com.minhope.system.service.ISysUserService;
import me.zhyd.oauth.cache.AuthDefaultStateCache;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.AuthStateUtils;/*** 第三方认证授权处理* * @author ruoyi*/
@RestController
@RequestMapping("/system/auth")
public class SysAuthController extends BaseController
{private AuthStateCache authStateCache;@Autowiredprivate ISysUserService userService;@Autowiredprivate SysPermissionService permissionService;@Autowiredprivate TokenService tokenService;@Autowiredprivate SysUserMapper userMapper;@Autowiredprivate ISysConfigService configService;private final static Map<String, String> auths = new HashMap<String, String>();{auths.put("dingtalk", "{\"clientId\":\"xxx\",\"clientSecret\":\"xxx\",\"redirectUri\":\"http://compute1.xxx.com:8085/social-login?source%3Ddingtalk\"}");authStateCache = AuthDefaultStateCache.INSTANCE;}/*** 认证授权* * @param source* @throws IOException*/@GetMapping("/binding/{source}")@ResponseBodypublic AjaxResult authBinding(@PathVariable("source") String source, HttpServletRequest request) throws IOException{LoginUser tokenUser = tokenService.getLoginUser(request);if (StringUtils.isNotNull(tokenUser) && userMapper.checkAuthUser(tokenUser.getUserId(), source) > 0){return error(source + "平台账号已经绑定");}String obj = auths.get(source);if (StringUtils.isEmpty(obj)){return error(source + "平台账号暂不支持");}JSONObject json = JSONObject.parseObject(obj);AuthRequest authRequest = AuthUtils.getAuthRequest(source, json.getString("clientId"), json.getString("clientSecret"), json.getString("redirectUri"), authStateCache);String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());System.out.println(authorizeUrl);return success(authorizeUrl);}@SuppressWarnings("unchecked")@GetMapping("/social-login/{source}")public AjaxResult socialLogin(@PathVariable("source") String source, AuthCallback callback, HttpServletRequest request){String obj = auths.get(source);if (StringUtils.isEmpty(obj)){return AjaxResult.error(10002, "第三方平台系统不支持或未提供来源");}JSONObject json = JSONObject.parseObject(obj);AuthRequest authRequest = AuthUtils.getAuthRequest(source, json.getString("clientId"), json.getString("clientSecret"), json.getString("redirectUri"), authStateCache);AuthResponse<AuthUser> response = authRequest.login(callback);if (response.ok()){LoginUser tokenUser = tokenService.getLoginUser(request);if (StringUtils.isNotNull(tokenUser)){SysUser user = userMapper.selectAuthUserByUuid(source + response.getData().getUuid());if (StringUtils.isNotNull(user)){String token = tokenService.createToken(SecurityUtils.getLoginUser());return success().put(Constants.TOKEN, token);}// 若已经登录则直接绑定系统账号SysAuthUser authUser = new SysAuthUser();authUser.setAvatar(response.getData().getAvatar());authUser.setUuid(source + response.getData().getUuid());authUser.setUserId(SecurityUtils.getUserId());authUser.setUserName(response.getData().getUsername());authUser.setNickName(response.getData().getNickname());authUser.setEmail(response.getData().getEmail());authUser.setSource(source);userMapper.insertAuthUser(authUser);String token = tokenService.createToken(SecurityUtils.getLoginUser());return success().put(Constants.TOKEN, token);}SysUser authUser = userMapper.selectAuthUserByUuid(source + response.getData().getUuid());if (StringUtils.isNotNull(authUser)){SysUser user = userService.selectUserByUserName(authUser.getUserName());if (StringUtils.isNull(user)){throw new ServiceException("登录用户:" + user.getUserName() + " 不存在");}else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())){throw new ServiceException("对不起,您的账号:" + user.getUserName() + " 已被删除");}else if (UserStatus.DISABLE.getCode().equals(user.getStatus())){throw new ServiceException("对不起,您的账号:" + user.getUserName() + " 已停用");}LoginUser loginUser = new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));String token = tokenService.createToken(loginUser);return success().put(Constants.TOKEN, token);} else {return AjaxResult.error(10002, "对不起,您没有绑定注册用户,请先注册后在个人中心绑定第三方授权信息!");}}return AjaxResult.error(10002, "对不起,授权信息验证不通过,请联系管理员");}/*** 取消授权*/@DeleteMapping(value = "/unlock/{authId}")public AjaxResult unlockAuth(@PathVariable Long authId){return toAjax(userMapper.deleteAuthUser(authId));}
}
4.2 SysAuthUser 第三方授权表数据类
package com.minhope.system.domain;import com.minhope.common.core.domain.BaseEntity;/*** 第三方授权表 sys_auth_user* * @author ruoyi*/
public class SysAuthUser extends BaseEntity
{private static final long serialVersionUID = 1L;/** 授权ID */private Long authId;/** 第三方平台用户唯一ID */private String uuid;/** 系统用户ID */private Long userId;/** 登录账号 */private String userName;/** 用户昵称 */private String nickName;/** 头像地址 */private String avatar;/** 用户邮箱 */private String email;/** 用户来源 */private String source;public Long getAuthId(){return authId;}public void setAuthId(Long authId){this.authId = authId;}public String getUuid(){return uuid;}public void setUuid(String uuid){this.uuid = uuid;}public Long getUserId(){return userId;}public void setUserId(Long userId){this.userId = userId;}public String getUserName(){return userName;}public void setUserName(String userName){this.userName = userName;}public String getNickName(){return nickName;}public void setNickName(String nickName){this.nickName = nickName;}public String getAvatar(){return avatar;}public void setAvatar(String avatar){this.avatar = avatar;}public String getEmail(){return email;}public void setEmail(String email){this.email = email;}public String getSource(){return source;}public void setSource(String source){this.source = source;}
}
4.3 认证授权工具类
package com.minhope.common.utils;import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.request.*;/*** 认证授权工具类* * @author ruoyi*/
public class AuthUtils
{@SuppressWarnings("deprecation")public static AuthRequest getAuthRequest(String source, String clientId, String clientSecret, String redirectUri,AuthStateCache authStateCache){AuthRequest authRequest = null;switch (source.toLowerCase()){case "dingtalk":authRequest = new AuthDingTalkRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build());
// authRequest = new AuthDingTalkV2Request(AuthConfig.builder()
// .clientId(clientId)
// .clientSecret(clientSecret)
// .redirectUri(redirectUri)
// .build());break;case "baidu":authRequest = new AuthBaiduRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;case "github":authRequest = new AuthGithubRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;case "gitee":authRequest = new AuthGiteeRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;case "weibo":authRequest = new AuthWeiboRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;
// case "coding":
// authRequest = new AuthCodingRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
// .redirectUri(redirectUri).codingGroupName("").build(), authStateCache);
// break;case "oschina":authRequest = new AuthOschinaRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;case "alipay":// 支付宝在创建回调地址时,不允许使用localhost或者127.0.0.1,所以这儿的回调地址使用的局域网内的ipauthRequest = new AuthAlipayRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).alipayPublicKey("").redirectUri(redirectUri).build(), authStateCache);break;case "qq":authRequest = new AuthQqRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;case "wechat_open":authRequest = new AuthWeChatOpenRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;case "csdn":authRequest = new AuthCsdnRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;case "taobao":authRequest = new AuthTaobaoRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;case "douyin":authRequest = new AuthDouyinRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;case "linkedin":authRequest = new AuthLinkedinRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;case "microsoft":authRequest = new AuthMicrosoftRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;case "mi":authRequest = new AuthMiRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;case "toutiao":authRequest = new AuthToutiaoRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;case "teambition":authRequest = new AuthTeambitionRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;case "pinterest":authRequest = new AuthPinterestRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;case "renren":authRequest = new AuthRenrenRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;case "stack_overflow":authRequest = new AuthStackOverflowRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).stackOverflowKey("").build(),authStateCache);break;case "huawei":authRequest = new AuthHuaweiRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;
// case "wechat_enterprise":
// authRequest = new AuthWeChatEnterpriseRequest(AuthConfig.builder().clientId(clientId)
// .clientSecret(clientSecret).redirectUri(redirectUri).agentId("").build(), authStateCache);
// break;case "kujiale":authRequest = new AuthKujialeRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;case "gitlab":authRequest = new AuthGitlabRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;case "meituan":authRequest = new AuthMeituanRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;case "eleme":authRequest = new AuthElemeRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build());break;case "wechat_mp":authRequest = new AuthWeChatMpRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;case "aliyun":authRequest = new AuthAliyunRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);break;default:break;}if (null == authRequest){throw new AuthException("未获取到有效的Auth配置");}return authRequest;}
}
4.4 sysUserMapper添加
/*** 根据用户编号查询授权列表** @param userId 用户编号* @return 授权列表*/public List<SysAuthUser> selectAuthUserListByUserId(Long userId);/*** 根据uuid查询用户信息** @param uuid 唯一信息* @return 结果*/public SysUser selectAuthUserByUuid(String uuid);/*** 校验source平台是否绑定** @param userId 用户编号* @param source 绑定平台* @return 结果*/public int checkAuthUser(@Param("userId") Long userId, @Param("source") String source);/*** 新增第三方授权信息** @param authUser 用户信息* @return 结果*/public int insertAuthUser(SysAuthUser authUser);/*** 根据编号删除第三方授权信息** @param authId 授权编号* @return 结果*/public int deleteAuthUser(Long authId);
4.5 ISysUserService 添加
/*** 根据用户编号查询授权列表** @param userId 用户编号* @return 授权列表*/public List<SysAuthUser> selectAuthUserListByUserId(Long userId);
4.6 SysUserServiceImpl添加
/*** 根据用户编号查询授权列表** @param userId 用户编号* @return 授权列表*/public List<SysAuthUser> selectAuthUserListByUserId(Long userId){return userMapper.selectAuthUserListByUserId(userId);}
4.7 SysUserMapper.xml添加
<resultMap id="SysAuthUserResult" type="SysAuthUser"><id property="authId" column="auth_id" /><result property="uuid" column="uuid" /><result property="userId" column="user_id" /><result property="userName" column="user_name" /><result property="nickName" column="nick_name" /><result property="avatar" column="avatar" /><result property="email" column="email" /><result property="source" column="source" /><result property="createTime" column="create_time" /></resultMap><select id="selectAuthUserByUuid" parameterType="String" resultMap="SysUserResult">select b.user_id as user_id, b.user_name as user_name, b.password as passwordfrom sys_auth_user a left join sys_user b on a.user_id = b.user_idwhere a.uuid = #{uuid} and b.del_flag = '0'</select><select id="selectAuthUserListByUserId" parameterType="Long" resultMap="SysAuthUserResult">select auth_id, uuid, user_id, user_name, nick_name, avatar, email, source, create_timefrom sys_auth_user where user_id = #{userId}</select><select id="checkAuthUser" parameterType="SysAuthUser" resultType="int">select count(1) from sys_auth_user where user_id=#{userId} and source=#{source} limit 1</select><insert id="insertAuthUser" parameterType="SysAuthUser">insert into sys_auth_user(<if test="uuid != null and uuid != ''">uuid,</if><if test="userId != null and userId != 0">user_id,</if><if test="userName != null and userName != ''">user_name,</if><if test="nickName != null and nickName != ''">nick_name,</if><if test="avatar != null and avatar != ''">avatar,</if><if test="email != null and email != ''">email,</if><if test="source != null and source != ''">source,</if>create_time)values(<if test="uuid != null and uuid != ''">#{uuid},</if><if test="userId != null and userId != 0">#{userId},</if><if test="userName != null and userName != ''">#{userName},</if><if test="nickName != null and nickName != ''">#{nickName},</if><if test="avatar != null and avatar != ''">#{avatar},</if><if test="email != null and email != ''">#{email},</if><if test="source != null and source != ''">#{source},</if>sysdate())</insert><delete id="deleteAuthUser" parameterType="Long">delete from sys_auth_user where auth_id = #{authId}</delete>
4.8 修改 SysProfileController
@GetMappingpublic AjaxResult profile(){LoginUser loginUser = getLoginUser();SysUser user = loginUser.getUser();AjaxResult ajax = AjaxResult.success(user);ajax.put("auths", userService.selectAuthUserListByUserId(user.getUserId())); //增加这句ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername()));ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername()));return ajax;}
4.9 修改 /framework/config/SecurityConfig
//justAuth第三方登录.antMatchers("/system/auth/binding/*", "/system/auth/social-login/*").permitAll()
5、数据库修改
DROP TABLE IF EXISTS sys_auth_user;
CREATE TABLE sys_auth_user (auth_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '授权ID',uuid VARCHAR(500) NOT NULL COMMENT '第三方平台用户唯一ID',user_id BIGINT(20) NOT NULL COMMENT '系统用户ID',user_name VARCHAR(30) NOT NULL COMMENT '登录账号',nick_name VARCHAR(30) DEFAULT '' COMMENT '用户昵称',avatar VARCHAR(500) DEFAULT '' COMMENT '头像地址',email VARCHAR(255) DEFAULT '' COMMENT '用户邮箱',source VARCHAR(255) DEFAULT '' COMMENT '用户来源',create_time DATETIME COMMENT '创建时间',PRIMARY KEY (auth_id)
) ENGINE=INNODB AUTO_INCREMENT=100 COMMENT = '第三方授权表';