bladex实现单点登录

简介: bladex实现单点登录

现在是: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:07
  No such property: code for class: Script1
  * @Return:
  */
  @Component
  @AllArgsConstructor
  public class CustomTokenGranter implements ITokenGranter {
    public static final String GRANT_TYPE = "custom";
    private final IUserService userService;
    private final ITenantService tenantService;
    @Override
    public 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地址修改成正式环境的地址
  • 别的没有了
相关文章
|
缓存 JavaScript API
bladex实现单点登录
bladex实现单点登录
2014 0
bladex实现单点登录
|
前端开发 JavaScript Java
springboot实现用户统一认证、管理(单点登录)
springboot实现用户统一认证、管理(单点登录)
|
SQL druid Java
springboot +logback+阿里数据源(druid)打印sql日志以及简化日志输出方式
springboot +logback+阿里数据源(druid)打印sql日志以及简化日志输出方式
2990 0
|
7月前
|
存储 监控 关系型数据库
InfluxDB 时序数据的高效解决方案
InfluxDB 是一种专为时间序列数据优化的开源数据库,支持高效存储、检索和分析大量时序数据。它采用 Tag-Key-Value 模型,提供高性能写入与查询能力,适合监控系统、物联网设备数据及实时分析等场景。相比传统关系型数据库(如 MySQL),InfluxDB 针对时序数据进行了架构优化,具备无模式设计、自动数据管理及灵活扩展性等优势。本文通过 Go 语言代码实战展示了如何连接、写入和查询 InfluxDB 数据,并介绍了其核心概念与应用场景,助力开发者快速上手时序数据库开发。
1300 0
InfluxDB 时序数据的高效解决方案
|
开发框架 前端开发 网络协议
Spring Boot结合Netty和WebSocket,实现后台向前端实时推送信息
【10月更文挑战第18天】 在现代互联网应用中,实时通信变得越来越重要。WebSocket作为一种在单个TCP连接上进行全双工通信的协议,为客户端和服务器之间的实时数据传输提供了一种高效的解决方案。Netty作为一个高性能、事件驱动的NIO框架,它基于Java NIO实现了异步和事件驱动的网络应用程序。Spring Boot是一个基于Spring框架的微服务开发框架,它提供了许多开箱即用的功能和简化配置的机制。本文将详细介绍如何使用Spring Boot集成Netty和WebSocket,实现后台向前端推送信息的功能。
3496 1
|
存储 Java Maven
使用Java实现OAuth 2.0认证授权
使用Java实现OAuth 2.0认证授权
1792 0
|
缓存 前端开发 程序员
JustAuth整合第三方登录组件
【10月更文挑战第3天】
515 57
|
前端开发 Java 数据库连接
35个项目,开源,开源!
35个项目,开源,开源!
1586 0
35个项目,开源,开源!
|
算法 JavaScript 数据可视化
基于leaflet-velocity的二维动态风场展示
本文讲解了leaflet-velocity插件,并利用插件进行了模拟的动态风场、洋流等信息的综合展示,让读者掌握集成方式。
1901 0
基于leaflet-velocity的二维动态风场展示
|
负载均衡 算法 Nacos
SpringCloud之LoadBalancer自定义负载均衡算法,基于nacos权重
ReactorLoadBalancer接口,实现自定义负载算法需要实现该接口,并实现choose逻辑,选取对应的节点。
1720 0