实现思路
三方系统(也就是需要跳转我们系统的系统),直接请求我们系统的登录页面,挂着token参数。

在我们系统登录界面,判断请求链接中有没有token,没有则正常走登录流程。

如果没有token,则重新写一个单点登录的接口,去请求。

在后台将拿到的token,去三方系统中鉴权,通过则继续登录,没有通过则直接返回到登录页面。

实现代码
前端
1.在login的vue页面中的created方法中,调用单点登录的方法。

created() {
 
     //平台单独的登录  2022年4月19日11:23:58
     this.getLoginByNameAndTokenJ();
  },

2.在methods中写函数的实现:

/**
     * 三方平台单点登陆系统 2022年4月19日11:22:33
     * 只传递token
     */
    getLoginByNameAndTokenJ(){
      //获取地址栏中的token
      var token = this.$route.query.token;
 
      //调用登录的接口
      if(token==''||token==undefined||token==null){
        //不是那边系统过来的,不走这个地方(阻止created的方法继续向下走)
        
      }else{
       //转圈圈,不要看到登陆页面,无感体验
        this.loading = true;
        var logininfo= {
          "token":token
        };
 
        //执行另一套登录操作
        //不是本系统的用户,去J平台登陆去
        this.$store.dispatch("LoginJHaveToken", logininfo).then(() => {
          this.$message.success("登录成功");
          this.loading = false;
          //判断当前角色
          getInfo().then((res) => {
            //获取角色名称
            var rolesName = res.roles[0];
            //获取所属场馆
            this.deptInfo = res.dept;
            sessionStorage.setItem("ssUserName", res.user.nickName);
            //如果是场馆管理员
            if (rolesName === 'changguanmanager') {
              this.$router.push({
                path: "/VenueKanban",
                query: {changguan: res, aa: 0},
                replace: true
              }).catch(() => {
              });
              //否则就是其他用户
            } else {
              this.$router.push({path: this.redirect || "/"}).catch(() => {
              });
            }
          });
        }).catch(err=> {
          console.log("有异常信息",err);
          //异常信息
          this.loading = false;
          if (this.captchaOnOff) {
            this.getCode();
          }
        });
      }
    },

3.在user.js中,实现LoginJHaveToken方法:

//平台带着token登录,不需要输入账号密码
    //密码都是123456,
    //还需要带着token验证一下
    LoginJHaveToken({ commit }, userInfo) {
      const token = userInfo.token
      const queryParams ={
        'token':token
      };
      return new Promise((resolve, reject) => {
        getLoginByJHaveToken(queryParams).then(res => {
          setToken(res.token)
          commit('SET_TOKEN', res.token)
          resolve()
        }).catch(error => {
          reject(error)
        })
      })
    },

4.在login.js中,实现getLoginByJHaveToken方法:

/**
  * 平台带着tonken进行登录
  *
  * @param queryParam
  * @returns {*}
  */
 export function getLoginByJHaveToken(queryParam) {
   return request({
     url: '/ToThirdPart/toThirdPartGetAuthJHaveToken',
     method: 'post',
     params: queryParam
   })
 }

后端
1.在/ToThirdPart/toThirdPartGetAuthJHaveToken控制器中实现登录的操作:

/**
* @Description: 平台带着token来系统里面登陆
* 这边需要做两个步骤:
* 1.检测数据库里面有没有这个用户名,有则不操作,无则添加
* 2.去平台验证一下Token是否有,有的话继续操作后面的登录
* 平台没有这个token,则直接打回去,不让上来
* @Return: com.ruoyi.common.core.domain.AjaxResult
*/
@PostMapping(“/toThirdPartGetAuthJHaveToken”)
@ApiOperation(value = “平台带着token过来登录”)
public AjaxResult toThirdPartGetAuthJHaveToken(String token) {

    //调用验证token的方法
    JSONObject jsonObject = checkJToken(token);
    String code = jsonObject.getString("code");
    Integer level = 0;
    String loginName = "";
    Long organId = null;
    //返回结果
    AjaxResult ajax = null;
    if (code.equals("0")) {
        //验证成功
        JSONObject dataObject = jsonObject.getJSONObject("data");
        //拿到其他的信息
        level = dataObject.getInteger("level");
        loginName = dataObject.getString("name");
        organId = dataObject.getLong("organId");
    } else {
        ajax = AjaxResult.error(jsonObject.getString("msg"));
        return ajax;
    }

    String isUserNameHas = "";
    //检测一下用户名存在不存在
    if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(loginName))) {
        isUserNameHas = "用户已存在,不需要执行添加的操作";
    } else {
        //用户不存在时,将用户添加到数据库中
        SysUser sysUser = new SysUser();
        //登录名
        sysUser.setUserName(loginName);
        //昵称
        sysUser.setNickName(loginName);
        //密码统一都是123456
        sysUser.setPassword(SecurityUtils.encryptPassword("123456"));
        //创建者,标识J平台过来的用户
        sysUser.setCreateBy("j_have_token");
        //创建日期
        sysUser.setCreateTime(new Date());
        //所属等级
        sysUser.setHierarchy(level);
        //明文
        sysUser.setMingwen("123456");
        //账户权限:为了区分是平台的用户还是本系统用户

        //id返回来之后需要加上
        sysUser.setDeptId(organId);

        //所属等级如果没有,则角色是全国的
        //1  省  2 市     3  区
        if (level == null) {
            //角色
            Long[] roleids = {104L};
            sysUser.setRoleIds(roleids);
        } else {
            Long[] roleids = {100L};
            sysUser.setRoleIds(roleids);
        }
        int rows = userService.insertUser(sysUser);
        if (rows > 0) {
            isUserNameHas = "添加成功";
        }
    }
    ajax = AjaxResult.success();
    // 生成令牌(不加验证码登录)
    String tokenNew = loginService.loginNoCode(loginName, "123456", null);
    ajax.put(Constants.TOKEN, tokenNew);
    ajax.put("isUserNameHas", isUserNameHas);
    ajax.put("msg", "登录成功");
    return ajax;
}

2.鉴权方法checkJToken,验证token是否存在,存在则返回用户信息,不存在则打回去:

/**
     * 检测一下J平台的token 对不对
     *
     * @param token
     * @return
     */
    public JSONObject checkJToken(String token) {
        JSONObject jsonObject = new JSONObject();
        //测试环境
        String baseUrl = "http://xxxxx/checkTokenRtnInfo?stk=" + token;
        HttpResponse d = HttpRequest.get(baseUrl)
                .header(HttpHeaders.CONTENT_TYPE, "application/json")
                .header(HttpHeaders.ACCEPT, "application/json")
                .execute();
        return (JSONObject) JSONObject.parse(d.body().toString());
    }

3.绕过验证码登录的方法,重写loginService.loginNoCode方法:

/**
     * 不加验证码登录
     *
     * @param username 用户名
     * @param password 密码
     * @param uuid 唯一标识
     * @return 结果
     */
    public String loginNoCode(String username, String password,  String uuid)
    {
        // 用户验证
        Authentication authentication = null;
        try
        {
            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
            authentication = authenticationManager
                    .authenticate(new UsernamePasswordAuthenticationToken(username, password));
        }
        catch (Exception e)
        {
            if (e instanceof BadCredentialsException)
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                throw new UserPasswordNotMatchException();
            }
            else
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
                throw new ServiceException(e.getMessage());
            }
        }
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        recordLoginInfo(loginUser.getUserId());
        // 生成token
        return tokenService.createToken(loginUser);
    }

最后就可以了,可能这种方式不是最好的,但是目前仅想到这种方法。

注意事项
因为若依的登录方法是带着验证码的,如果不带,则会提示验证码失效

目前登录传参的方式是post,相对比较安全点。

三方系统请求的时候,参数是在链接中挂着,不是很靠谱。
————————————————

原文链接:https://blog.csdn.net/qq_34137397/article/details/124287795

Logo

快速构建 Web 应用程序

更多推荐