cuilei
5 天以前 3a3b5bc665f526269bd622a70812bead173fbdf2
企业微信H5登录改回静默授权方式
已修改3个文件
371 ■■■■ 文件已修改
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/controller/ThirdLoginController.java 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/impl/ThirdAppDingtalkServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/impl/ThirdAppWechatEnterpriseServiceImpl.java 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/controller/ThirdLoginController.java
@@ -317,11 +317,11 @@
            builder.append("&response_type=code");
            // 应用授权作用域。
            // snsapi_base:静默授权,可获取成员的的基础信息(UserId与DeviceId);
            //builder.append("&scope=snsapi_base");
            builder.append("&scope=snsapi_privateinfo"); // 手动授权作用域
            builder.append("&scope=snsapi_base");//静默授权
            //builder.append("&scope=snsapi_privateinfo"); // 手动授权作用域
            // 重定向后会带上state参数,长度不可超过128个字节
            builder.append("&state=").append(state);
            builder.append("&agentid=").append(config.getAgentId()); // 补充AgentID
            //builder.append("&agentid=").append(config.getAgentId()); // 补充AgentID(手动授权时需要)
            // 终端使用此参数判断是否需要带上身份信息
            builder.append("#wechat_redirect");
            url = builder.toString();
@@ -435,4 +435,149 @@
        }
    }
    //企业微信适配手动授权接口调整
    ///**
    // * 企业微信/钉钉 OAuth2登录回调
    // *
    // * @param code
    // * @param state
    // * @param response
    // * @return
    // */
    //@ResponseBody
    //@GetMapping("/oauth2/{source}/callback")
    //public String oauth2LoginCallback(
    //        @PathVariable("source") String source,
    //        // 企业微信返回的code
    //        @RequestParam(value = "code", required = false) String code,
    //        // 钉钉返回的code
    //        @RequestParam(value = "authCode", required = false) String authCode,
    //        @RequestParam("state") String state,
    //        @RequestParam(value = "is_reject", required = false) String isReject,
    //        HttpServletResponse response) {
    //    SysUser loginUser;
    //    if (ThirdAppConfig.WECHAT_ENTERPRISE.equalsIgnoreCase(source)) {
    //        log.info("【企业微信】OAuth2登录进入callback:code=" + code + ", state=" + state);
    //        // 1. 判定用户拒绝授权的3种场景:
    //        //    - 场景1:is_reject=true(企业微信明确标识拒绝)
    //        //    - 场景2:code为null(未返回有效授权凭证)
    //        //    - 场景3:code存在但无效(调用API失败)
    //        boolean isUserReject = "true".equals(isReject) || code == null;
    //        if (isUserReject) {
    //            log.info("用户明确拒绝企业微信授权(is_reject={}, code={}", isReject, code);
    //            // 构造含error=access_denied的重定向地址,前端据此识别
    //            String errorRedirect = buildErrorRedirect(state, "access_denied");
    //            try {
    //                response.sendRedirect(errorRedirect);
    //                return "用户拒绝授权,已重定向";
    //            } catch (IOException e) {
    //                log.error("拒绝授权重定向失败", e);
    //                return "重定向失败";
    //            }
    //        }
    //
    //        // 2. 尝试用code获取用户信息(code存在但可能无效)
    //        loginUser = thirdAppWechatEnterpriseService.oauth2Login(code);
    //        if (loginUser == null) {
    //            log.info("企业微信授权失败(code无效)");
    //            String errorRedirect = buildErrorRedirect(state, "invalid_code");
    //            try {
    //                response.sendRedirect(errorRedirect);
    //                return "授权失败,已重定向";
    //            } catch (IOException e) {
    //                log.error("授权失败重定向失败", e);
    //                return "重定向失败";
    //            }
    //        }
    //        loginUser = thirdAppWechatEnterpriseService.oauth2Login(code);
    //        if (loginUser == null) {
    //            return "登录失败";
    //        }
    //    } else if (ThirdAppConfig.DINGTALK.equalsIgnoreCase(source)) {
    //        log.info("【钉钉】OAuth2登录进入callback:authCode=" + authCode + ", state=" + state);
    //        loginUser = thirdAppDingtalkService.oauth2Login(authCode);
    //        if (loginUser == null) {
    //            return "登录失败";
    //        }
    //    } else {
    //        return "不支持的source";
    //    }
    //    try {
    //
    //        //update-begin-author:taoyan date:2022-6-30 for: 工作流发送消息 点击消息链接跳转办理页面
    //        String redirect = "";
    //        if (state.indexOf("?") > 0) {
    //            String[] arr = state.split("\\?");
    //            state = arr[0];
    //            if(arr.length>1){
    //                redirect = arr[1];
    //            }
    //        }
    //
    //        String token = saveToken(loginUser);
    //        // ============ 新增 Shiro 登录逻辑 ============
    //        JwtToken jwtToken = new JwtToken(token);
    //        SecurityUtils.getSubject().login(jwtToken);
    //        state += "/h5/oauth2-app/login?oauth2LoginToken=" + URLEncoder.encode(token, "UTF-8");
    //        //update-begin---author:wangshuai ---date:20220613  for:[issues/I5BOUF]oauth2 钉钉无法登录------------
    //        state += "&thirdType=" + source;
    //        //state += "&thirdType=" + "wechat_enterprise";
    //        if (redirect != null && redirect.length() > 0) {
    //            state += "&" + redirect;
    //        }
    //        //update-end-author:taoyan date:2022-6-30 for: 工作流发送消息 点击消息链接跳转办理页面
    //
    //        //update-end---author:wangshuai ---date:20220613  for:[issues/I5BOUF]oauth2 钉钉无法登录------------
    //        log.info("OAuth2登录重定向地址: " + state);
    //        try {
    //            response.sendRedirect(state);
    //            return "ok";
    //        } catch (IOException e) {
    //            e.printStackTrace();
    //            return "重定向失败";
    //        }
    //    } catch (UnsupportedEncodingException e) {
    //        e.printStackTrace();
    //        return "解码失败";
    //    }
    //}
    //
    ///**
    // * 构造企业微信授权拒绝时的错误重定向地址
    // * 适配规则:state参数长度≤128字节,保留原始业务参数,附加error标识
    // */
    //private String buildErrorRedirect(String originalState, String errorCode) {
    //    // 1. 拆分原始state中的基础路径和业务参数(避免破坏原有state结构)
    //    String baseState = originalState;
    //    String businessParams = "";
    //    if (originalState.contains("?")) {
    //        String[] stateParts = originalState.split("\\?", 2); // 只拆分成两部分
    //        baseState = stateParts[0]; // 基础路径(如https://fastwoke.cn:8087)
    //        businessParams = stateParts[1]; // 原始业务参数(如redirect=xxx)
    //    }
    //
    //    // 2. 构造错误参数(error=xxx),并拼接原始业务参数
    //    StringBuilder errorParams = new StringBuilder();
    //    errorParams.append("error=").append(errorCode); // 核心错误标识
    //    if (!businessParams.isEmpty()) {
    //        errorParams.append("&").append(businessParams); // 附加原始业务参数
    //    }
    //
    //    // 3. 拼接完整的重定向地址(格式:baseState/h5/oauth2-app/login?errorParams)
    //    // 注意:企业微信要求重定向地址需与授权链接中的redirect_uri域名一致
    //    StringBuilder errorRedirect = new StringBuilder(baseState);
    //    errorRedirect.append("/h5/oauth2-app/login?").append(errorParams);
    //
    //    // 4. 校验state长度(企业微信限制≤128字节),超长时截断非关键参数
    //    String redirectUrl = errorRedirect.toString();
    //    if (redirectUrl.getBytes().length > 128) {
    //        log.warn("错误重定向地址超长,截断处理: {}", redirectUrl);
    //        // 只保留基础路径和error参数,舍弃其他业务参数
    //        redirectUrl = baseState + "/h5/oauth2-app/login?error=" + errorCode;
    //    }
    //
    //    log.info("企业微信拒绝授权重定向地址: {}", redirectUrl);
    //    return redirectUrl;
    //}
}
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/impl/ThirdAppDingtalkServiceImpl.java
@@ -827,7 +827,7 @@
            return null;
        }
        int agentId = thirdAppConfig.getDingtalk().getAgentIdInt();
        return JdtMessageAPI.recallMessage(String.valueOf(agentId), msgTaskId, getAccessToken());
        return JdtMessageAPI.recallMessage(agentId, msgTaskId, getAccessToken());
    }
    /**
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/impl/ThirdAppWechatEnterpriseServiceImpl.java
@@ -1038,17 +1038,7 @@
        if (accessToken == null) {
            return null;
        }
        // 通过code获取用户信息(包含user_ticket)
        JSONObject userInfoResult = this.getUserInfoByCode(code, accessToken);
        if (userInfoResult == null || userInfoResult.getInteger("errcode") != 0) {
            log.error("获取企业微信用户信息失败,code: {}", code);
            return null;
        }
        String appUserId = userInfoResult.getString("UserId");
        String userTicket = userInfoResult.getString("user_ticket"); // 手动授权返回的用户票据
        String appUserId = this.getUserIdByThirdCode(code, accessToken);
        if (appUserId != null) {
            // 判断第三方用户表有没有这个人
            LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();
@@ -1056,63 +1046,18 @@
            queryWrapper.or().eq(SysThirdAccount::getThirdUserId, appUserId);
            queryWrapper.eq(SysThirdAccount::getThirdType, THIRD_TYPE);
            SysThirdAccount thirdAccount = sysThirdAccountService.getOne(queryWrapper);
            // 通过user_ticket获取用户详细信息(包含手机号等敏感信息)
            JSONObject userDetail = this.getUserDetailByTicket(userTicket, accessToken);
            String mobile = userDetail.getString("mobile");
            if (thirdAccount != null) {
                // 更新手机号(如果有)
                if (mobile != null && !mobile.isEmpty()) {
                    thirdAccount.setPhone(mobile);
                    sysThirdAccountService.updateById(thirdAccount);
                }
                return this.getSysUserByThird(thirdAccount, null, appUserId, accessToken);
            } else {
                // 直接创建新账号,包含手机号信息
                // 直接创建新账号
                User appUser = JwUserAPI.getUserByUserid(appUserId, accessToken);
                ThirdLoginModel tlm = new ThirdLoginModel(THIRD_TYPE, appUser.getUserid(), appUser.getName(), appUser.getAvatar(), mobile);
                ThirdLoginModel tlm = new ThirdLoginModel(THIRD_TYPE, appUser.getUserid(), appUser.getName(), appUser.getAvatar());
                thirdAccount = sysThirdAccountService.saveThirdUser(tlm);
                return this.getSysUserByThird(thirdAccount, appUser, null, null);
            }
        }
        return null;
    }
    /**
     * 通过code获取用户信息(包含user_ticket)
     */
    private JSONObject getUserInfoByCode(String code, String accessToken) {
        String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo" +
                "?access_token=" + accessToken +
                "&code=" + code;
        try {
            String result = String.valueOf(RestUtil.get(url));
            return JSONObject.parseObject(result);
        } catch (Exception e) {
            log.error("获取企业微信用户信息异常", e);
            return null;
        }
    }
    /**
     * 通过user_ticket获取用户详细信息(包含手机号等敏感信息)
     */
    private JSONObject getUserDetailByTicket(String userTicket, String accessToken) {
        String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserdetail";
        JSONObject params = new JSONObject();
        params.put("user_ticket", userTicket);
        try {
            String result = String.valueOf(RestUtil.post(url + "?access_token=" + accessToken, JSONObject.parseObject(params.toJSONString())));
//            String result = String.valueOf(RestUtil.post(url + "?access_token=" + accessToken, params.toJSONString()));
            return JSONObject.parseObject(result);
        } catch (Exception e) {
            log.error("获取企业微信用户详细信息异常", e);
            return new JSONObject(); // 返回空对象避免NPE
        }
    }
    /**
     * 根据第三方账号获取本地账号,如果不存在就创建
@@ -1126,24 +1071,14 @@
    private SysUser getSysUserByThird(SysThirdAccount thirdAccount, User appUser, String appUserId, String accessToken) {
        String sysUserId = thirdAccount.getSysUserId();
        if (oConvertUtils.isNotEmpty(sysUserId)) {
            SysUser sysUser = userMapper.selectById(sysUserId);
            if (sysUser != null && StringUtils.isBlank(sysUser.getPhone())) {
                //如果有用户,并且没有电话信息,更新进电话号码
                SysUser user = new SysUser()
                        .setId(sysUser.getId())
                        .setPhone(thirdAccount.getPhone());
                userMapper.updateById(user);
            }
            return sysUser;
            return userMapper.selectById(sysUserId);
        } else {
            // 如果没有 sysUserId ,说明没有绑定账号,获取到手机号之后进行绑定
            if (appUser == null) {
                appUser = JwUserAPI.getUserByUserid(appUserId, accessToken);
            }
            appUser.setMobile(thirdAccount.getPhone());
            // 判断系统里是否有这个用户,根据工号匹配
            SysUser sysUser = userMapper.getUserByWorkNo(thirdAccount.getThirdUserId());
            //SysUser sysUser = userMapper.getUserByPhone(appUser.getMobile());
            if (sysUser != null) {
                thirdAccount.setAvatar(appUser.getAvatar());
                thirdAccount.setRealname(appUser.getName());
@@ -1151,13 +1086,6 @@
                thirdAccount.setThirdUserUuid(appUser.getUserid());
                thirdAccount.setSysUserId(sysUser.getId());
                sysThirdAccountService.updateById(thirdAccount);
                if (StringUtils.isBlank(sysUser.getPhone())) {
                    //如果没有手机号码,更新
                    SysUser user = new SysUser()
                            .setId(sysUser.getId())
                            .setPhone(appUser.getMobile());
                    userMapper.updateById(user);
                }
                return sysUser;
            } else {
                // 没有就走创建逻辑
@@ -1167,4 +1095,142 @@
        }
    }
    //适配手动授权登录,获取用户手机号码调整修改
//    /**
//     * OAuth2登录,成功返回登录的SysUser,失败返回null
//     */
//    public SysUser oauth2Login(String code) {
//        String accessToken = this.getAppAccessToken();
//        if (accessToken == null) {
//            return null;
//        }
//
//        // 通过code获取用户信息(包含user_ticket)
//        JSONObject userInfoResult = this.getUserInfoByCode(code, accessToken);
//        if (userInfoResult == null || userInfoResult.getInteger("errcode") != 0) {
//            log.error("获取企业微信用户信息失败,code: {}", code);
//            return null;
//        }
//
//        String appUserId = userInfoResult.getString("UserId");
//        String userTicket = userInfoResult.getString("user_ticket"); // 手动授权返回的用户票据
//
//        if (appUserId != null) {
//            // 判断第三方用户表有没有这个人
//            LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();
//            queryWrapper.eq(SysThirdAccount::getThirdUserUuid, appUserId);
//            queryWrapper.or().eq(SysThirdAccount::getThirdUserId, appUserId);
//            queryWrapper.eq(SysThirdAccount::getThirdType, THIRD_TYPE);
//            SysThirdAccount thirdAccount = sysThirdAccountService.getOne(queryWrapper);
//
//            // 通过user_ticket获取用户详细信息(包含手机号等敏感信息)
//            JSONObject userDetail = this.getUserDetailByTicket(userTicket, accessToken);
//            String mobile = userDetail.getString("mobile");
//
//            if (thirdAccount != null) {
//                // 更新手机号(如果有)
//                if (mobile != null && !mobile.isEmpty()) {
//                    thirdAccount.setPhone(mobile);
//                    sysThirdAccountService.updateById(thirdAccount);
//                }
//                return this.getSysUserByThird(thirdAccount, null, appUserId, accessToken);
//            } else {
//                // 直接创建新账号,包含手机号信息
//                User appUser = JwUserAPI.getUserByUserid(appUserId, accessToken);
//                ThirdLoginModel tlm = new ThirdLoginModel(THIRD_TYPE, appUser.getUserid(), appUser.getName(), appUser.getAvatar(), mobile);
//                thirdAccount = sysThirdAccountService.saveThirdUser(tlm);
//                return this.getSysUserByThird(thirdAccount, appUser, null, null);
//            }
//        }
//        return null;
//    }
//
//    /**
//     * 通过code获取用户信息(包含user_ticket)
//     */
//    private JSONObject getUserInfoByCode(String code, String accessToken) {
//        String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo" +
//                "?access_token=" + accessToken +
//                "&code=" + code;
//        try {
//            String result = String.valueOf(RestUtil.get(url));
//            return JSONObject.parseObject(result);
//        } catch (Exception e) {
//            log.error("获取企业微信用户信息异常", e);
//            return null;
//        }
//    }
//
//    /**
//     * 通过user_ticket获取用户详细信息(包含手机号等敏感信息)
//     */
//    private JSONObject getUserDetailByTicket(String userTicket, String accessToken) {
//        String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserdetail";
//        JSONObject params = new JSONObject();
//        params.put("user_ticket", userTicket);
//
//        try {
//            String result = String.valueOf(RestUtil.post(url + "?access_token=" + accessToken, JSONObject.parseObject(params.toJSONString())));
////            String result = String.valueOf(RestUtil.post(url + "?access_token=" + accessToken, params.toJSONString()));
//            return JSONObject.parseObject(result);
//        } catch (Exception e) {
//            log.error("获取企业微信用户详细信息异常", e);
//            return new JSONObject(); // 返回空对象避免NPE
//        }
//    }
    //适配手动授权登录,获取用户手机号码并存入或更新
    ///**
    // * 根据第三方账号获取本地账号,如果不存在就创建
    // *
    // * @param thirdAccount
    // * @param appUser
    // * @param appUserId
    // * @param accessToken
    // * @return
    // */
    //private SysUser getSysUserByThird(SysThirdAccount thirdAccount, User appUser, String appUserId, String accessToken) {
    //    String sysUserId = thirdAccount.getSysUserId();
    //    if (oConvertUtils.isNotEmpty(sysUserId)) {
    //        SysUser sysUser = userMapper.selectById(sysUserId);
    //        if (sysUser != null && StringUtils.isBlank(sysUser.getPhone())) {
    //            //如果有用户,并且没有电话信息,更新进电话号码
    //            SysUser user = new SysUser()
    //                    .setId(sysUser.getId())
    //                    .setPhone(thirdAccount.getPhone());
    //            userMapper.updateById(user);
    //        }
    //        return sysUser;
    //    } else {
    //        // 如果没有 sysUserId ,说明没有绑定账号,获取到手机号之后进行绑定
    //        if (appUser == null) {
    //            appUser = JwUserAPI.getUserByUserid(appUserId, accessToken);
    //        }
    //        appUser.setMobile(thirdAccount.getPhone());
    //        // 判断系统里是否有这个用户,根据工号匹配
    //        SysUser sysUser = userMapper.getUserByWorkNo(thirdAccount.getThirdUserId());
    //        //SysUser sysUser = userMapper.getUserByPhone(appUser.getMobile());
    //        if (sysUser != null) {
    //            thirdAccount.setAvatar(appUser.getAvatar());
    //            thirdAccount.setRealname(appUser.getName());
    //            thirdAccount.setThirdUserId(appUser.getUserid());
    //            thirdAccount.setThirdUserUuid(appUser.getUserid());
    //            thirdAccount.setSysUserId(sysUser.getId());
    //            sysThirdAccountService.updateById(thirdAccount);
    //            if (StringUtils.isBlank(sysUser.getPhone())) {
    //                //如果没有手机号码,更新
    //                SysUser user = new SysUser()
    //                        .setId(sysUser.getId())
    //                        .setPhone(appUser.getMobile());
    //                userMapper.updateById(user);
    //            }
    //            return sysUser;
    //        } else {
    //            // 没有就走创建逻辑
    //            return sysThirdAccountService.createUser(appUser.getMobile(), appUser.getUserid());
    //        }
    //
    //    }
    //}
}