package com.epmet.service.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.epmet.commons.thirdplat.apiservice.AbstractApiService; import com.epmet.commons.thirdplat.bean.ThirdPlatUserInfo; import com.epmet.commons.tools.exception.EpmetErrorCode; import com.epmet.commons.tools.exception.RenException; import com.epmet.commons.tools.security.dto.TokenDto; import com.epmet.commons.tools.utils.*; import com.epmet.dto.PaCustomerDTO; import com.epmet.dto.UserDTO; import com.epmet.dto.form.*; import com.epmet.dto.result.GovWebOperLoginResultDTO; import com.epmet.dto.result.SsoLoginResultDTO; import com.epmet.dto.result.ThirdplatApiserviceResultDTO; import com.epmet.dto.result.UserTokenResultDTO; import com.epmet.enums.ThirdPlatformEnum; import com.epmet.feign.EpmetUserFeignClient; import com.epmet.feign.EpmetUserOpenFeignClient; import com.epmet.feign.OperCrmOpenFeignClient; import com.epmet.jwt.JwtTokenProperties; import com.epmet.jwt.JwtTokenUtils; import com.epmet.redis.SsoRedis; import com.epmet.service.SsoService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; /** * @Author zxc * @DateTime 2021/1/18 下午4:35 */ @Service @Slf4j public class SsoServiceImpl implements SsoService { Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private SsoRedis ssoRedis; @Autowired private JwtTokenUtils jwtTokenUtils; @Autowired private JwtTokenProperties jwtTokenProperties; @Autowired private EpmetUserOpenFeignClient epmetUserOpenFeignClient; @Autowired private OperCrmOpenFeignClient operCrmOpenFeignClient; @Autowired private EpmetUserFeignClient epmetUserFeignClient; /** * @Description 0、入口:得到token * @Param formDTO * @author zxc * @date 2021/1/18 下午4:59 */ @Override public SsoLoginResultDTO ssoLogin(SsoLoginFormDTO formDTO) { String customerId = getCustomerId(formDTO.getAppId()); String userId = ""; Result apiServiceResult = operCrmOpenFeignClient.getApiServiceByCustomerId(new ApiServiceFormDTO(customerId)); if (!apiServiceResult.success()) { throw new RenException("【SSO登录】调用OperCrm获取ApiService接口失败:", apiServiceResult.getInternalMsg()); } if (apiServiceResult.getData() == null || StringUtils.isBlank(apiServiceResult.getData().getApiServiceName())) { throw new RenException("【SSO登录】调用OperCrm获取ApiService,查询到的结果为空:", apiServiceResult.toString()); } ThirdPlatUserInfo userInfo; try { AbstractApiService apiService = (AbstractApiService) SpringContextUtils.getBean(apiServiceResult.getData().getApiServiceName()); userInfo = apiService.getUserInfoByTicket(formDTO.getTicket()); } catch (Exception e) { throw new RenException(e.getMessage()); } if (null == userInfo){ throw new RenException(EpmetErrorCode.THIRD_PLAT_REQUEST_ERROR.getCode(), "【SSO登录】调用第三方平台查询用户信息失败,用户信息为空"); } UserInfoFormDTO userInfoFormDTO = new UserInfoFormDTO(); userInfoFormDTO.setApp(formDTO.getApp()); userInfoFormDTO.setUid(userInfo.getOpenId()); userInfoFormDTO.setName(userInfo.getName()); userInfoFormDTO.setMobile(userInfo.getMobile()); Result userDTOResult = epmetUserOpenFeignClient.saveUserInfo(userInfoFormDTO); if (!userDTOResult.success()){ throw new RenException("【SSO登录】新增或更新user_weChat失败"); } userId = userDTOResult.getData().getId(); if (StringUtils.isBlank(userId)){ throw new RenException("【SSO登录】userId为空,生成token失败"); } //生成业务token String token = this.generateToken(formDTO.getApp(), formDTO.getClient(), userId); //存放Redis if (StringUtils.isBlank(customerId)) { throw new RenException("【SSO登录】customerId为空,缓存放置token失败"); } this.disposeTokenDto(formDTO.getApp(), formDTO.getClient(), userId, token, customerId); return new SsoLoginResultDTO(token); } @Override public UserTokenResultDTO thirdLoginOper(SsoLoginOperFormDTO formDTO) { ThirdPlatUserInfo thirdUser; try { ThirdPlatformEnum platformEnum = ThirdPlatformEnum.getEnum(formDTO.getPlatform()); String apiService = platformEnum.getApiService(); AbstractApiService apiServiceImpl = (AbstractApiService) SpringContextUtils.getBean(apiService); thirdUser = apiServiceImpl.getUserInfoByTicket(formDTO.getThirdToken()); } catch (Exception e) { throw new RenException(e.getMessage()); } //获取用户信息 GovWebOperLoginFormDTO form = new GovWebOperLoginFormDTO(); form.setCustomerId(thirdUser.getCustomerId()); form.setMobile(thirdUser.getMobile()); Result result = epmetUserFeignClient.getStaffIdAndPwd(form); //todo userId 写死测试 3f7f852ce22c511aa67ecb695395295d start GovWebOperLoginResultDTO demo = new GovWebOperLoginResultDTO(); demo.setUserId("3f7f852ce22c511aa67ecb695395295d"); result = new Result<>(); result.ok(demo); //test end if (!result.success() || null == result.getData() || null == result.getData().getUserId()) { logger.error("根据手机号查询PC工作端登陆人员信息失败,返回10003账号不存在"); throw new RenException(EpmetErrorCode.ERR10003.getCode()); } //4、生成token返回,且将TokenDto存到redis //生成业务token GovWebOperLoginResultDTO epmetUser = result.getData(); String token = this.generateToken(formDTO.getApp(), formDTO.getClient(), epmetUser.getUserId()); //存放Redis this.disposeTokenDto(formDTO.getApp(), formDTO.getClient(), epmetUser.getUserId(), token, thirdUser.getCustomerId()); UserTokenResultDTO userTokenResultDTO = new UserTokenResultDTO(); userTokenResultDTO.setToken(token); return userTokenResultDTO; } /** * @Description token放缓存 * @Param formDTO * @Param userId * @Param token * @Param customerId * @author zxc * @date 2021/1/18 下午5:32 */ public void disposeTokenDto(String app, String client, String userId, String token, String customerId) { int expire = jwtTokenProperties.getExpire(); TokenDto tokenDto = new TokenDto(); tokenDto.setCustomerId(customerId); tokenDto.setApp(app); tokenDto.setClient(client); tokenDto.setUserId(userId); tokenDto.setToken(token); tokenDto.setUpdateTime(System.currentTimeMillis()); tokenDto.setExpireTime(jwtTokenUtils.getExpiration(token).getTime()); ssoRedis.set(tokenDto, expire); log.info("截止时间:" + DateUtils.format(jwtTokenUtils.getExpiration(token), "yyyy-MM-dd HH:mm:ss")); } /** * @Description 居民端登陆生成业务token的key * @Param app * @Param client * @Param userId * @author zxc * @date 2021/1/18 下午5:14 */ private String generateToken(String app, String client, String userId) { Map map = new HashMap<>(16); map.put("app", app); map.put("client", client); map.put("userId", userId); String token = jwtTokenUtils.createToken(map); log.info("app:" + app + ";client:" + client + ";userId:" + userId + ";生成token[" + token + "]"); return token; } /** * @Description 获取customerId * @Param appId * @author zxc * @date 2021/1/19 下午1:47 */ public String getCustomerId(String appId){ JSONObject jsonObject = new JSONObject(); String customerMsgUrl = "https://epmet-cloud.elinkservice.cn/api/third/customermp/getcustomermsg/"; String data = HttpClientManager.getInstance().sendPostByJSON(customerMsgUrl + appId, JSON.toJSONString(jsonObject)).getData(); log.info("调用third服务,根据appId查询客户信息:httpclient->url:" + customerMsgUrl + ",结果->" + data); JSONObject toResult = JSON.parseObject(data); Result mapToResult = ConvertUtils.mapToEntity(toResult, Result.class); if (null != toResult.get("code")) { mapToResult.setCode(((Integer) toResult.get("code")).intValue()); } if (!mapToResult.success()) { log.error(String.format("根据appId查询客户信息失败,对应appId->" + appId)); throw new RenException(mapToResult.getMsg()); } Object publicCustomerResultDTO = mapToResult.getData(); JSONObject json = JSON.parseObject(publicCustomerResultDTO.toString()); Map map = (Map) json.get("customer"); PaCustomerDTO customer = ConvertUtils.mapToEntity(map, PaCustomerDTO.class); log.info("小程序登陆third服务获取客户用户信息PaCustomerDTO->" + customer); return customer.getId(); } public static void main(String[] args) { String url = "https://epmet-ext9.elinkservice.cn/platform/unifiedAuth/loginCheck"; String platformToken = "1348803062424166401_dd08e23b0d524879a5c67e7f2ffd1468"; String appId = "7a5aec009ba4eba8e254ee64fe3775e1"; String appKey = "14faef9af508d1c253b720ea5a43f9de"; String appSecret = "38e7c2604c8dd33c445705d25eebbfc12a2f7ed8a87111e9e10a40312d3a1595"; long ts = System.currentTimeMillis(); String message = appId + appKey + appSecret + ts; String accessToken = DigestUtils.md5Hex(message.getBytes(StandardCharsets.UTF_8)); //ThirdPlatformEnum platformEnum = ThirdPlatformEnum.getEnum("pyld"); JSONObject jsonObject = new JSONObject(); jsonObject.put("platformToken", platformToken); Map headerMap = new HashMap<>(4); headerMap.put("AppKey", appKey); headerMap.put("Timestamp", ts); headerMap.put("AccessToken", accessToken); Result stringResult = HttpClientManager.getInstance().sendPost(url, url.startsWith("https://"), jsonObject.toJSONString(), headerMap); System.out.println(stringResult); } }