若依实现系统单点登录(可绕过验证码)

2438915b01b4b8a49d85fe0e89a9372e.png

大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂

前言

现在是:2022年4月19日19:56:56

昨天写了个bladex的单点登录,回想起来还是比较复杂的,今天又收到了个在若依里面实现单点登录。具体是这样的:别的系统中访问我们的系统,但是用户已经在那边系统登录过了,跳转到这边无需在来一次登录,直接上本系统中继续后续的操作。

实现思路

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

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

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

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

实现代码

前端

1.在loginvue页面中的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,则直接打回去,不让上来
     * @author: 穆雄雄
     * @date: 2022/4/19 上午 11:38
     * @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);
    }

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

注意事项

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

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

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

  • 13
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 27
    评论
若依app实现若依后端的单点登录,可以参考以下步骤: 1. 在若依的后端系统实现单点登录的功能。这可以通过在后端代码添加相关逻辑来实现。具体而言,可以在用户登录成功后生成一个用户认证的token,并将该token返回给前端。 2. 在若依的app,将拿到的token发送给其他系统进行鉴权。这可以通过调用其他系统提供的接口来实现。如果鉴权成功,则继续登录;如果鉴权失败,则返回登录页面。 3. 在若依的app的前端页面,可以在登录页面的created方法调用单点登录的方法。具体而言,可以在created方法调用一个获取token并发送给后端进行鉴权的函数。 总结来说,若依app实现若依后端的单点登录的步骤包括在若依的后端系统实现单点登录功能,将拿到的token发送给其他系统进行鉴权,以及在若依的app的前端页面调用单点登录的方法。通过这些步骤,就可以实现若依app和若依后端的单点登录。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [若依实现系统单点登录(可绕过验证码)](https://blog.csdn.net/qq_34137397/article/details/124287795)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

穆雄雄

哎,貌似还没开张来着呢~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值