From 7a0dd449cc2f49c18c2bc324a3ed283b5f1b3cf5 Mon Sep 17 00:00:00 2001 From: jiangqs <jiangqs> Date: 星期二, 09 五月 2023 17:43:38 +0800 Subject: [PATCH] Merge branch 'master' of ssh://sinata.cn:20202/java/HongRuiTang into master --- ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/AgentConfigVo.java | 20 ++++++ ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java | 24 ++++++++ ruoyi-auth/src/main/java/com/ruoyi/auth/controller/QwH5Controller.java | 14 +++- ruoyi-auth/src/main/java/com/ruoyi/auth/service/QywxInnerService.java | 105 ++++++++++++++++++++++++++++++++++ ruoyi-auth/src/main/resources/bootstrap.yml | 7 +- 5 files changed, 161 insertions(+), 9 deletions(-) diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/AgentConfigVo.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/AgentConfigVo.java new file mode 100644 index 0000000..9181fc5 --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/AgentConfigVo.java @@ -0,0 +1,20 @@ +package com.ruoyi.system.api.model; + +import lombok.Data; + +/** + * {"agentid":"1000024","corpid":"ww11400938eb1b91bc","signature":"fb52026ab2dc4b604037dfd411f17772657a19a8","nonceStr":"Wm3WZYTPz0wzccnW","timestamp":1683622343} + */ +@Data +public class AgentConfigVo { + + private String agentid; + + private String corpid; + + private String signature; + + private String nonceStr; + + private String timestamp; +} diff --git a/ruoyi-auth/src/main/java/com/ruoyi/auth/controller/QwH5Controller.java b/ruoyi-auth/src/main/java/com/ruoyi/auth/controller/QwH5Controller.java index bdc8861..048fafd 100644 --- a/ruoyi-auth/src/main/java/com/ruoyi/auth/controller/QwH5Controller.java +++ b/ruoyi-auth/src/main/java/com/ruoyi/auth/controller/QwH5Controller.java @@ -5,10 +5,7 @@ import com.ruoyi.auth.service.SysLoginService; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.security.service.TokenService; -import com.ruoyi.system.api.model.OauthUrlVo; -import com.ruoyi.system.api.model.OauthUserVo; -import com.ruoyi.system.api.model.QwH5LoginVo; -import com.ruoyi.system.api.model.QwUserDetailDto; +import com.ruoyi.system.api.model.*; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -71,4 +68,13 @@ // 2、生成Token return R.ok(tokenService.createQwH5Token(qwH5LoginVo)); } + + @GetMapping("/h5/getAgentConfig") + @ApiOperation("通过code获取访问用户登录") + public R<AgentConfigVo> getAgentConfig(@ApiParam(value = "url", required = true) String url) throws IOException { + AgentConfigVo agentConfigVo = qywxInnerService.getAgentConfig(url); + return R.ok(agentConfigVo); + } + + } diff --git a/ruoyi-auth/src/main/java/com/ruoyi/auth/service/QywxInnerService.java b/ruoyi-auth/src/main/java/com/ruoyi/auth/service/QywxInnerService.java index d36e18a..b425ba0 100644 --- a/ruoyi-auth/src/main/java/com/ruoyi/auth/service/QywxInnerService.java +++ b/ruoyi-auth/src/main/java/com/ruoyi/auth/service/QywxInnerService.java @@ -1,14 +1,29 @@ package com.ruoyi.auth.service; import com.alibaba.fastjson.JSONObject; +import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.A; import com.ruoyi.auth.config.QywxInnerConfig; import com.ruoyi.auth.utils.RestUtils; import com.ruoyi.common.core.constant.Constants; import com.ruoyi.common.core.exception.ServiceException; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.system.api.model.AgentConfigVo; +import org.apache.commons.codec.binary.Hex; +import org.apache.commons.lang3.ObjectUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.cache.RedisCache; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Calendar; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; @Service public class QywxInnerService { @@ -18,21 +33,34 @@ @Autowired private QywxInnerConfig qywxInnerConfig; + @Autowired + private StringRedisTemplate redisTemplate; + public String getAccessToken(){ + + String accessToken = redisTemplate.opsForValue().get(Constants.QY_WX_ACCESS_TOKEN_KEY); + if(!StringUtils.isEmpty(accessToken)){ + return accessToken; + } String corpId = qywxInnerConfig.getCorpId(); String agentSecret = qywxInnerConfig.getAgentSecret(); String accessTokenUrl = String.format(qywxInnerConfig.getAccessTokenUrl(), corpId, agentSecret); JSONObject response = RestUtils.get(accessTokenUrl); + // 获取错误日志 if(response.containsKey(Constants.QY_WX_ERR_CODE) && response.getInteger(Constants.QY_WX_ERR_CODE) != 0){ logger.error(response.toString()); throw new ServiceException("获取企业微信ACCESS_TOKEN异常"); } - return response.getString(Constants.QY_WX_ACCESS_TOKEN); + accessToken = response.getString(Constants.QY_WX_ACCESS_TOKEN); + Long expiresIn = response.getLong(Constants.QY_WX_EXPIRES_IN); + expiresIn = expiresIn - 100; + redisTemplate.opsForValue().set(Constants.QY_WX_ACCESS_TOKEN_KEY, accessToken, expiresIn, TimeUnit.SECONDS); + return accessToken; } @@ -96,4 +124,79 @@ return detailResponse; } + + + + public AgentConfigVo getAgentConfig(String url) { + + AgentConfigVo agentConfigVo = new AgentConfigVo(); + agentConfigVo.setAgentid(qywxInnerConfig.getAgentId()); + agentConfigVo.setCorpid(qywxInnerConfig.getCorpId()); + + //临时票据 + String ticket = getJsApiTicket(); + if (StringUtils.isEmpty(ticket)) { + throw new ServiceException("获取票据异常"); + } + //当前时间戳 转成秒 + long timestamp = System.currentTimeMillis() / 1000; + //随机字符串 + String nonceStr = Constants.QY_WX_NONCE_STR; + String signature = getSignature(ticket, nonceStr, timestamp, url); + agentConfigVo.setTimestamp(String.valueOf(timestamp)); + agentConfigVo.setNonceStr(nonceStr); + agentConfigVo.setSignature(signature); + + return agentConfigVo; + } + + + private String getSignature(String ticket, String nonceStr, long timestamp, String url) { + String unEncryptStrBase = "jsapi_ticket=%s&noncestr=%s×tamp=%s&url=%s"; + try { + String unEncryptStr = String.format(unEncryptStrBase, ticket, nonceStr, timestamp, url); + + logger.info("----------------unEncryptStr-------------"); + logger.info(unEncryptStr); + + MessageDigest digest = MessageDigest.getInstance("SHA-1"); + // 调用digest方法,进行加密操作 + byte[] cipherBytes = digest.digest(unEncryptStr.getBytes()); + String encryptStr = Hex.encodeHexString(cipherBytes); + logger.info("----------------getSignature-------------"); + logger.info(encryptStr); + return encryptStr; + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return null; + } + + + /** + * 获取ticket + * @paran type + * @return + */ + public String getJsApiTicket() { + String accessToken = getAccessToken(); + String ticket = redisTemplate.opsForValue().get(Constants.QY_WX_TICKET_KEY); + if(!StringUtils.isEmpty(ticket)){ + return ticket; + } + String url = String.format(qywxInnerConfig.getJsapiTicketAgentUrl(), accessToken); + + JSONObject response = RestUtils.get(url); + if(response.containsKey(Constants.QY_WX_ERR_CODE) && response.getInteger(Constants.QY_WX_ERR_CODE) != 0){ + logger.error(response.toString()); + throw new ServiceException("获取企业微信信息异常"); + } + + ticket = response.getString(Constants.QY_WX_TICKET); + Long expiresIn = response.getLong(Constants.QY_WX_EXPIRES_IN); + expiresIn = expiresIn - 100; + redisTemplate.opsForValue().set(Constants.QY_WX_TICKET_KEY, ticket, expiresIn, TimeUnit.SECONDS); + + return ticket; + } } diff --git a/ruoyi-auth/src/main/resources/bootstrap.yml b/ruoyi-auth/src/main/resources/bootstrap.yml index 9878fc2..ad760b2 100644 --- a/ruoyi-auth/src/main/resources/bootstrap.yml +++ b/ruoyi-auth/src/main/resources/bootstrap.yml @@ -24,11 +24,10 @@ shared-configs: - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} -#自建应用配置 非代开发不需要 具体自建应用配置大家写表里就行 qywx-inner: - corpId: ww78cbcfad600119af - agentId: 1000005 - agentSecret: 2xMP3DaamA4-zTu6KtsF_y83OSJRXK5UspB8hWKkXmI + corpId: ww11400938eb1b91bc + agentId: 1000024 + agentSecret: -wuQ2EBxNT9BJa40LdpFqyxI_8RqrZTCUNiabzBasi8 authorizeState: HONGRUITANG suiteSecret: "" token: "" diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java index f0caeed..0e77ab0 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java @@ -117,11 +117,35 @@ */ public static final String QY_WX_ERR_CODE = "errcode"; + + public static final String QY_WX_NONCE_STR = "Wm3WZYTPz0wzccnW"; + + /** + * 企业微信返回码 调用接口凭证KEY + */ + public static final String QY_WX_ACCESS_TOKEN_KEY = "qy_wx_access_token"; + + /** + * 企业微信返回码 调用接口ticket KEY + */ + public static final String QY_WX_TICKET_KEY = "qy_wx_ticket_token"; + + + /** * 企业微信返回码 调用接口凭证 */ public static final String QY_WX_ACCESS_TOKEN = "access_token"; + /** + * 企业微信返回码 调用接口凭证 + */ + public static final String QY_WX_EXPIRES_IN = "expires_in"; + + + public static final String QY_WX_TICKET = "ticket"; + + /** * 成员UserID -- Gitblit v1.7.1