Houjie
6 天以前 bb839b724afdaf9b4ea8a80c2d8963d2b9c2934c
企业微信静默登录修改手动授权登录
已修改4个文件
158 ■■■■ 文件已修改
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/controller/ThirdLoginController.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/entity/SysThirdAccount.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/model/ThirdLoginModel.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/impl/ThirdAppWechatEnterpriseServiceImpl.java 138 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/controller/ThirdLoginController.java
@@ -9,7 +9,6 @@
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.util.JwtUtil;
@@ -17,7 +16,6 @@
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.RestUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.shiro.JwtToken;
import org.jeecg.config.thirdapp.ThirdAppConfig;
import org.jeecg.config.thirdapp.ThirdAppTypeItemVo;
import org.jeecg.modules.base.service.BaseCommonService;
@@ -203,7 +201,7 @@
        String token = JwtUtil.sign(user.getUsername(), user.getPassword());
        redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
        // 设置超时时间
        redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, EXPIRE_TIME / 1000);
        redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
        return token;
    }
@@ -308,15 +306,17 @@
            // 企业的CorpID
            builder.append("?appid=").append(config.getClientId());
            // 授权后重定向的回调链接地址,请使用urlencode对链接进行处理
            String redirectUri ="https://fastwoke.cn:8087/jeecg-boot/sys/thirdLogin/oauth2/wechat_enterprise/callback";
            String redirectUri = "https://fastwoke.cn:8087/jeecg-boot/sys/thirdLogin/oauth2/wechat_enterprise/callback";
            builder.append("&redirect_uri=").append(URLEncoder.encode(redirectUri, "UTF-8"));
            // 返回类型,此时固定为:code
            builder.append("&response_type=code");
            // 应用授权作用域。
            // snsapi_base:静默授权,可获取成员的的基础信息(UserId与DeviceId);
            builder.append("&scope=snsapi_base");
//            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("#wechat_redirect");
            url = builder.toString();
@@ -399,7 +399,7 @@
            }
            String token = saveToken(loginUser);
            state += "/oauth2-app/login?oauth2LoginToken=" + URLEncoder.encode(token, "UTF-8");
            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";
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/entity/SysThirdAccount.java
@@ -77,4 +77,7 @@
    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private java.util.Date updateTime;
    /**手机号*/
    @Excel(name = "手机号", width = 15)
    private java.lang.String phone;
}
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/model/ThirdLoginModel.java
@@ -33,6 +33,11 @@
    private String avatar;
    /**
     * 第三方登录 手机号
     */
    private String phone;
    /**
     * 账号 后缀第三方登录 防止账号重复
     */
    private String suffix;
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/impl/ThirdAppWechatEnterpriseServiceImpl.java
@@ -1031,31 +1031,31 @@
    /**
     * OAuth2登录,成功返回登录的SysUser,失败返回null
     */
    public SysUser oauth2Login(String code) {
        String accessToken = this.getAppAccessToken();
        if (accessToken == null) {
            return null;
        }
        String appUserId = this.getUserIdByThirdCode(code, accessToken);
        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);
            if (thirdAccount != null) {
                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());
                thirdAccount = sysThirdAccountService.saveThirdUser(tlm);
                return this.getSysUserByThird(thirdAccount, appUser, null, null);
            }
        }
        return null;
    }
//    public SysUser oauth2Login(String code) {
//        String accessToken = this.getAppAccessToken();
//        if (accessToken == null) {
//            return null;
//        }
//        String appUserId = this.getUserIdByThirdCode(code, accessToken);
//        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);
//            if (thirdAccount != null) {
//                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());
//                thirdAccount = sysThirdAccountService.saveThirdUser(tlm);
//                return this.getSysUserByThird(thirdAccount, appUser, null, null);
//            }
//        }
//        return null;
//    }
    /**
     * 根据第三方账号获取本地账号,如果不存在就创建
@@ -1093,4 +1093,92 @@
        }
    }
    /**
     * 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());
                tlm.setPhone(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
        }
    }
}