大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂
前言
现在是:2022年4月17日16:19:51
在实际开发中,有时候我们有这样的需求,即,一个体系中的用户是共通的,比如统一体系下,A系统的张三,去B系统中不需要重新注册即可直接登录,今天简单的整理了下,希望对大家有帮助。
效果如下
同步用户至别的系统中
1.配置代理
找到vue.config.js
文件,在devServer
节点下面配置一个代理:
"/programme": {//本地服务接口地址target: "http://127.0.0.1:6776/api/trainingprograme/",//远程演示服务地址,可用于直接启动项目//target: "http://farbeat.ruixm.club:7665",changeOrigin: true,pathRewrite: {"^/programme": "",},},
2.然后vue页面中写请求方法:
/*跳转到训练方案的系统*//*跳转到训练方案的系统*/goTraingProgramme() {//先获取当前用户的信息getCurrentUserInfo().then(res=>{const data = res.data.data;//请求训练方案的系统,将当前用户信息同步过去goTraingProgramme(data).then(() => {var loginForm = {username: data.account,password: data.password,};console.log("loginForm",loginForm);//异步进行登录this.$store.dispatch("LoginPrammeSystem", loginForm).then(()=> {this.$message({type: "warning",message: "正在进入训练方案系统……"});//跳转到训练方案的系统,正式环境下需要更改window.open("http://localhost:1889/");},()=>{this.$message({type: "error",message: "登录失败,请重试!"});});});});},
3.在system/user.js中先获取当前用户的信息,拿着获取到的用户名和密码去训练方案系统登录去
/*** 获取当前用户的信息* @returns {*}*/export const getCurrentUserInfo = () => {return request({url: "/api/blade-user/getCurrentUserInfo",method: "get",});};
4.后台控制器UserController中的获取当前用户信息的代码如下:
/*** 获取当前用户的信息*/@GetMapping("/getCurrentUserInfo")@ApiOperationSupport(order = 5)@ApiOperation(value = "获取当前用户的信息")public R getCurrentUserInfo() {User user = userService.getById(AuthUtil.getUserId());return R.data(user);}
5.请求训练方案的系统,将当前用户信息同步过去,在js文件中添加如下请求方法:
/*** 跳转到训练方案的系统* 直接跳过去,暂时不带token* @returns {*}*/export const goTraingProgramme = (userInfo) => {return request({url: "/programme/getModelLogin",method: "post",params: {userInfo,},});};
6.在训练方案的系统中需要将三方系统中同步过来的信息加到数据库中,为后面的单点登录做准备,代码如下:
/*** 1.直接传过来用户对象,想存什么价就存什么* 2.检测一下运动员表中有没有这个人,有的话跳过,没有则需要加进来* 3.根据账号去查询用户表中有没有这个账户,有的话执行更新操作* 4.用户表作用没有这个账户,则执行添加的操作** @param userInfo* @return 成功的信息*/@ApiOperation("跳转到训练方案的接口,然后调用登陆的方法,然后去首页")@ApiImplicitParams({@ApiImplicitParam(paramType = "header", dataType = "String", name = "Authorization",value = "token令牌,请联系系统人员分配地址", required = true)})@PostMapping(value = "/getModelLogin")public String getModelLogin(String userInfo) {/*** 1.检测运动员表里面有没有传过来的用户,如果有,不添加* 如果没有则添加* 2.根据用户名查询有没有这个人,有:检查密码对不对* 3.没有这个账户,则添加一条记录进去*/JSONObject userObject = JSONObject.parseObject(userInfo);JSONObject jsonObject = new JSONObject();//去查询运动员表QueryWrapper<Athletes> athletesQueryWrapper = new QueryWrapper<>();athletesQueryWrapper.lambda().eq(Athletes:: getWorkcode,userObject.getString("id"));athletesQueryWrapper.last("limit 1");Athletes athletes = athletesService.getOne(athletesQueryWrapper);if(athletes==null){//没有找到,添加进去athletes = new Athletes();athletes.setWorkcode(userObject.getString("id"));athletes.setAname(userObject.getString("id"));athletesService.save(athletes);}//检测用户表/*LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();lambdaQueryWrapper.eq(User::getAccount,userObject.getString("account"));*/User user = userService.userByAccount(userObject.getString("tenantId"),userObject.getString("account"));if(user==null){user = new User();}//创建人是管理员user.setCreateUser(1123598821738675201L);user.setUserType(userObject.getInteger("userType"));user.setPhone(userObject.getString("phone"));//角色(和张三的角色一样)user.setRoleId("1426105929175019521");user.setAccount(userObject.getString("account"));user.setDeptId("1123598813738675201");user.setPassword(userObject.getString("password"));user.setName(userObject.getString("name"));//调用修改和添加的方法userService.saveOrUpdate(user);jsonObject.put("code",200);jsonObject.put("msg","操作成功");return jsonObject.toJSONString();}
以上内容就是请求训练方案系统,然后将信息放在库里面,下面我们来实现一下登录的功能这是重点
单点登录
1.配置代理信息
/*请求登陆的方法*/"/modelLogin": {//本地服务接口地址,这是测试环境,正式环境需要更改下地址target: "http://127.0.0.1:6776/blade-auth/",changeOrigin: true,pathRewrite: {"^/modelLogin": "",},},
2.vue
中调用请求登录(关键代码,其实上面都已经放过了):
//异步进行登录this.$store.dispatch("LoginPrammeSystem", loginForm).then(() => {//跳转到指定连接(正式环境需要更改地址)window.open("http://localhost:1889/");});
3.在modules/user.js
中封装LoginPrammeSystem
方法:
//登录训练方案的系统LoginPrammeSystem({ commit }, userInfo) {return new Promise((resolve, reject) => {LoginPrammeSystem("000000", userInfo.username, userInfo.password).then((res) => {const data = res.data;if (data.error_description) {Message({message: data.error_description,type: "error",});} else {commit("SET_TOKEN", data.access_token);commit("SET_REFRESH_TOKEN", data.refresh_token);commit("SET_TENANT_ID", data.tenant_id);commit("SET_USER_INFO", data);commit("DEL_ALL_TAG");commit("CLEAR_LOCK");}resolve(data);}).catch((error) => {reject(error);});});},
4.在api/user.js
中去请求训练方案系统中登录方法:
/*登录训练方案的系统*/export const LoginPrammeSystem = (tenantId, username, password) =>request({//去训练方案里面的系统登录url: "/modelLogin/oauth/token",method: "post",headers: {"Tenant-Id": tenantId,},params: {tenantId,username,password,grant_type: "custom",scope: "all",type: "",},});
5.在训练方案的鉴权登录的模块中,添加一个类:CustomTokenGranter
,代码如下:
package org.springblade.modules.auth.granter;import lombok.AllArgsConstructor;import org.springblade.core.log.exception.ServiceException;import org.springblade.core.tool.utils.DigestUtil;import org.springblade.core.tool.utils.Func;import org.springblade.modules.auth.enums.UserEnum;import org.springblade.modules.auth.provider.ITokenGranter;import org.springblade.modules.auth.provider.TokenParameter;import org.springblade.modules.auth.utils.TokenUtil;import org.springblade.modules.system.entity.Tenant;import org.springblade.modules.system.entity.UserInfo;import org.springblade.modules.system.service.ITenantService;import org.springblade.modules.system.service.IUserService;import org.springframework.stereotype.Component;/*** @Description: 别的系统登陆本系统* @author: 穆雄雄* @date: 2022年4月17日11:04:07No such property: code for class: Script1* @Return:*/@Component@AllArgsConstructorpublic class CustomTokenGranter implements ITokenGranter {public static final String GRANT_TYPE = "custom";private final IUserService userService;private final ITenantService tenantService;@Overridepublic UserInfo grant(TokenParameter tokenParameter) {String tenantId = tokenParameter.getArgs().getStr("tenantId");String username = tokenParameter.getArgs().getStr("username");String password = tokenParameter.getArgs().getStr("password");UserInfo userInfo = null;if (Func.isNoneBlank(username, password)) {// 获取租户信息Tenant tenant = tenantService.getByTenantId(tenantId);if (TokenUtil.judgeTenant(tenant)) {throw new ServiceException(TokenUtil.USER_HAS_NO_TENANT_PERMISSION);}// 获取用户类型String userType = tokenParameter.getArgs().getStr("userType");// 根据不同用户类型调用对应的接口返回数据,用户可自行拓展if (userType.equals(UserEnum.WEB.getName())) {userInfo = userService.userInfo(tenantId, username,password, UserEnum.WEB);} else if (userType.equals(UserEnum.APP.getName())) {userInfo = userService.userInfo(tenantId, username, DigestUtil.hex(password), UserEnum.APP);} else {userInfo = userService.userInfo(tenantId, username, DigestUtil.hex(password), UserEnum.OTHER);}}return userInfo;}}
6.在 TokenGranter缓存池 中的静态代码块中添加如下代码:
//客户端自定义登录的方法GRANTER_POOL.put(CustomTokenGranter.GRANT_TYPE, SpringUtil.getBean(CustomTokenGranter.class));
注意事项
- 记得将本地的localhost地址修改成正式环境的地址
- 别的没有了