forked from rongchao/epmet-cloud-rizhao
13 changed files with 381 additions and 113 deletions
@ -0,0 +1,35 @@ |
|||||
|
package com.epmet.dto.form; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
|
||||
|
/** |
||||
|
* @Author zxc |
||||
|
* @CreateTime 2020/7/7 11:12 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class ComponentVerifyTicketFormDTO implements Serializable { |
||||
|
|
||||
|
private static final long serialVersionUID = -6547893374373422628L; |
||||
|
|
||||
|
/** |
||||
|
* 第三方平台 appid |
||||
|
*/ |
||||
|
private String appId; |
||||
|
|
||||
|
/** |
||||
|
* 时间戳,单位:s |
||||
|
*/ |
||||
|
private Integer CreateTime; |
||||
|
|
||||
|
/** |
||||
|
* 固定为:"component_verify_ticket" |
||||
|
*/ |
||||
|
private String InfoType = "component_verify_ticket"; |
||||
|
|
||||
|
/** |
||||
|
* Ticket 内容 |
||||
|
*/ |
||||
|
private String componentVerifyTicket; |
||||
|
} |
@ -0,0 +1,25 @@ |
|||||
|
package com.epmet.dto.form; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
|
||||
|
/** |
||||
|
* @Author zxc |
||||
|
* @CreateTime 2020/7/7 10:28 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class WeChatPlatformAuthCodeFormDTO implements Serializable { |
||||
|
|
||||
|
private static final long serialVersionUID = -9047434066325122697L; |
||||
|
|
||||
|
/** |
||||
|
* 预授权码 |
||||
|
*/ |
||||
|
private String authCode; |
||||
|
|
||||
|
/** |
||||
|
* 有效期,单位:秒 |
||||
|
*/ |
||||
|
private Integer expiresIn; |
||||
|
} |
@ -0,0 +1,45 @@ |
|||||
|
package com.epmet.redis; |
||||
|
|
||||
|
import com.epmet.commons.tools.redis.RedisUtils; |
||||
|
import com.epmet.constant.ModuleConstant; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.data.redis.core.RedisTemplate; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import java.util.concurrent.TimeUnit; |
||||
|
|
||||
|
/** |
||||
|
* @Author zxc |
||||
|
* @CreateTime 2020/7/7 9:33 |
||||
|
*/ |
||||
|
@Slf4j |
||||
|
@Component |
||||
|
public class RedisThird { |
||||
|
|
||||
|
@Autowired |
||||
|
private RedisUtils redisUtils; |
||||
|
@Autowired |
||||
|
private RedisTemplate redisTemplate; |
||||
|
|
||||
|
public void setComponentAccessToken (String accessToken){ |
||||
|
redisTemplate.opsForValue().set(ModuleConstant.COMPONENT_ACCESS_TOKEN, accessToken, 60 * 60 * 2, TimeUnit.SECONDS); |
||||
|
} |
||||
|
|
||||
|
public String getComponentAccessToken(String key){ |
||||
|
return redisTemplate.opsForValue().get(key).toString(); |
||||
|
} |
||||
|
|
||||
|
public String getComponentVerifyTicket(String key){ |
||||
|
return redisTemplate.opsForValue().get(key).toString(); |
||||
|
} |
||||
|
|
||||
|
public void setComponentVerifyTicket(String verifyTicket){ |
||||
|
redisTemplate.opsForValue().set(ModuleConstant.TICKET_REDIS_KEY+ModuleConstant.TICKET_UNDERLINE_KEY, verifyTicket, 60 * 10, TimeUnit.SECONDS); |
||||
|
} |
||||
|
|
||||
|
public void setPreAuthCode(String authCode){ |
||||
|
redisTemplate.opsForValue().set(ModuleConstant.PRE_AUTH_CODE, authCode, 60 * 10, TimeUnit.SECONDS); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,46 @@ |
|||||
|
package com.epmet.service; |
||||
|
|
||||
|
import com.epmet.commons.tools.security.dto.TokenDto; |
||||
|
import com.epmet.dto.form.ThirdPlatformEventFormDTO; |
||||
|
import com.epmet.dto.form.WeChatPlatformAuthCodeFormDTO; |
||||
|
import com.epmet.dto.result.ResultBean; |
||||
|
import org.springframework.web.bind.annotation.RequestBody; |
||||
|
|
||||
|
/** |
||||
|
* @Author zxc |
||||
|
* @CreateTime 2020/7/6 11:19 |
||||
|
*/ |
||||
|
public interface ComponentVerifyTicketService { |
||||
|
|
||||
|
/** |
||||
|
* 获得授权事件的票据 |
||||
|
* |
||||
|
* @param timestamp 时间戳 |
||||
|
* @param nonce 随机数 |
||||
|
* @param msgSignature 消息体签名 |
||||
|
* @param postData 消息体 |
||||
|
* @return 如果获得只需要返回 SUCCESS |
||||
|
* @Author zxc |
||||
|
*/ |
||||
|
void parseRequest(ThirdPlatformEventFormDTO formDTO); |
||||
|
|
||||
|
/** |
||||
|
* @Description 定时获取 ticket |
||||
|
* @author zxc |
||||
|
*/ |
||||
|
void ticketJob(); |
||||
|
|
||||
|
/** |
||||
|
* @Description 每个预授权码有效期为 10 分钟。需要先获取令牌才能调用 获取预授权码 |
||||
|
* @author zxc |
||||
|
*/ |
||||
|
void preAuthCode(); |
||||
|
|
||||
|
/** |
||||
|
* @Description |
||||
|
* @param formDTO |
||||
|
* @author zxc |
||||
|
*/ |
||||
|
void weChatPlatformAuthCode(WeChatPlatformAuthCodeFormDTO formDTO); |
||||
|
|
||||
|
} |
@ -1,24 +0,0 @@ |
|||||
package com.epmet.service; |
|
||||
|
|
||||
import com.epmet.dto.form.ThirdPlatformEventFormDTO; |
|
||||
|
|
||||
/** |
|
||||
* @Author zxc |
|
||||
* @CreateTime 2020/7/6 9:12 |
|
||||
*/ |
|
||||
public interface DbyWechatExtService { |
|
||||
|
|
||||
/** |
|
||||
* 获得授权事件的票据 |
|
||||
* |
|
||||
* @param timestamp 时间戳 |
|
||||
* @param nonce 随机数 |
|
||||
* @param msgSignature 消息体签名 |
|
||||
* @param postData 消息体 |
|
||||
* @return 如果获得只需要返回 SUCCESS |
|
||||
* @Author zxc |
|
||||
*/ |
|
||||
String parseRequest(ThirdPlatformEventFormDTO formDTO); |
|
||||
|
|
||||
|
|
||||
} |
|
@ -0,0 +1,144 @@ |
|||||
|
package com.epmet.service.impl; |
||||
|
|
||||
|
import com.alibaba.fastjson.JSON; |
||||
|
import com.alibaba.fastjson.JSONObject; |
||||
|
import com.epmet.commons.tools.security.dto.TokenDto; |
||||
|
import com.epmet.constant.ModuleConstant; |
||||
|
import com.epmet.constant.ThirdPlatformConstant; |
||||
|
import com.epmet.dto.form.ThirdPlatformEventFormDTO; |
||||
|
import com.epmet.dto.form.WeChatPlatformAuthCodeFormDTO; |
||||
|
import com.epmet.exception.AesException; |
||||
|
import com.epmet.redis.RedisThird; |
||||
|
import com.epmet.service.ComponentVerifyTicketService; |
||||
|
import com.epmet.util.WXBizMsgCrypt; |
||||
|
import com.epmet.util.WXXmlToMapUtil; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.apache.commons.collections4.MapUtils; |
||||
|
import org.apache.commons.lang3.StringUtils; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.util.HashMap; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
import static com.epmet.constant.ThirdPlatformConstant.*; |
||||
|
|
||||
|
/** |
||||
|
* @Author zxc |
||||
|
* @CreateTime 2020/7/6 11:21 |
||||
|
*/ |
||||
|
@Slf4j |
||||
|
@Service |
||||
|
public class ComponentVerifyTicketServiceImpl implements ComponentVerifyTicketService { |
||||
|
|
||||
|
@Autowired |
||||
|
private RedisThird redisThird; |
||||
|
|
||||
|
/** |
||||
|
* @Description 获得授权事件的票据 |
||||
|
* @param formDTO |
||||
|
* @author zxc |
||||
|
*/ |
||||
|
@Override |
||||
|
public void parseRequest(ThirdPlatformEventFormDTO formDTO) { |
||||
|
String msgSignature = formDTO.getMsgSignature(); |
||||
|
String nonce = formDTO.getNonce(); |
||||
|
String postData = formDTO.getPostData(); |
||||
|
String timeStamp = formDTO.getTimeStamp(); |
||||
|
log.info(ModuleConstant.START_RECEIVE); |
||||
|
try { |
||||
|
//这个类是微信官网提供的解密类,需要用到消息校验Token 消息加密Key和服务平台appid
|
||||
|
WXBizMsgCrypt pc = new WXBizMsgCrypt(ThirdPlatformConstant.PLATFORM_COMPONENT_TOKEN, ThirdPlatformConstant.PLATFORM_AES_KEY, ThirdPlatformConstant.PLATFORM_APP_ID); |
||||
|
String xml = pc.decryptMsg(msgSignature, timeStamp, nonce, postData); |
||||
|
// 将xml转为map
|
||||
|
Map<String, String> result = WXXmlToMapUtil.xmlToMap(xml); |
||||
|
String componentVerifyTicket = MapUtils.getString(result,ModuleConstant.TICKET_KEY); |
||||
|
if (StringUtils.isNotEmpty(componentVerifyTicket)) { |
||||
|
// 存储平台授权票据,保存ticket
|
||||
|
redisThird.setComponentVerifyTicket(componentVerifyTicket); |
||||
|
} else { |
||||
|
throw new RuntimeException(ModuleConstant.ERROR_TICKET); |
||||
|
} |
||||
|
} catch (AesException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
log.info(ModuleConstant.END_TICKET); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @Description 定时获取票据 |
||||
|
* @param |
||||
|
* @author zxc |
||||
|
*/ |
||||
|
@Override |
||||
|
public void ticketJob() { |
||||
|
log.info("====================开始执行定时任务获取令牌【component_access_token】===================="); |
||||
|
Map<String, String> reMap; |
||||
|
try { |
||||
|
// 核心定时器,每一个小时执行一次
|
||||
|
String componentVerifyTicket = redisThird.getComponentVerifyTicket(ModuleConstant.TICKET_UNDERLINE_KEY); |
||||
|
JSONObject jsonObject = new JSONObject(); |
||||
|
jsonObject.put(ModuleConstant.COMPONENT_APPID, PLATFORM_APP_ID); |
||||
|
jsonObject.put(ModuleConstant.COMPONENT_APPSECRET, PLATFORM_APP_SECRET); |
||||
|
jsonObject.put(ModuleConstant.TICKET_UNDERLINE_KEY, componentVerifyTicket); |
||||
|
// String post = OkHttpHelper.post(API_COMPONENT_TOKEN_URl, JSON.toJSONString(jsonObject));
|
||||
|
String post = null; |
||||
|
log.info("====================返回post结果:" + post); |
||||
|
HashMap<String, String> hashMap = JSON.parseObject(post, HashMap.class); |
||||
|
String componentAccessToken = hashMap.get(ModuleConstant.COMPONENT_ACCESS_TOKEN); |
||||
|
if (StringUtils.isNotEmpty(componentAccessToken)) { |
||||
|
redisThird.setComponentAccessToken(componentAccessToken); |
||||
|
} else { |
||||
|
throw new RuntimeException(ModuleConstant.FAILURE_ACCESS_TOKEN); |
||||
|
} |
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
log.info(ModuleConstant.SUCCESS_ACCESS_TOKEN); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @Description 定时获取预授权码 |
||||
|
* @param |
||||
|
* @author zxc |
||||
|
*/ |
||||
|
@Override |
||||
|
public void preAuthCode() { |
||||
|
log.info("====================开始执行定时任务获取预授权码【pre_auth_code】===================="); |
||||
|
try { |
||||
|
// String accessToken = redisTemplate.opsForValue().get(ModuleConstant.COMPONENT_ACCESS_TOKEN).toString();
|
||||
|
String accessToken = redisThird.getComponentAccessToken(ModuleConstant.COMPONENT_ACCESS_TOKEN); |
||||
|
JSONObject jsonObject = new JSONObject(); |
||||
|
jsonObject.put(ModuleConstant.COMPONENT_APPID, PLATFORM_APP_ID); |
||||
|
// String post = OkHttpHelper.post(API_CREATE_PREAUTHCODE_URL + accessToken, JSON.toJSONString(jsonObject));
|
||||
|
String post = null; |
||||
|
log.info("====================返回post结果:" + post); |
||||
|
HashMap<String, String> hashMap = JSON.parseObject(post, HashMap.class); |
||||
|
String authCode = hashMap.get("pre_auth_code"); |
||||
|
if (StringUtils.isNotEmpty(authCode)) { |
||||
|
redisThird.setPreAuthCode(authCode); |
||||
|
// redisTemplate.opsForValue().set("pre_auth_code", authCode, 60 * 10, TimeUnit.SECONDS);
|
||||
|
} else { |
||||
|
throw new RuntimeException("微信开放平台,第三方平台获取【预授权码】失败"); |
||||
|
} |
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
log.info("====================结束执行定时任务获取预授权码【pre_auth_code】===================="); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void weChatPlatformAuthCode(WeChatPlatformAuthCodeFormDTO formDTO) { |
||||
|
String authCode = formDTO.getAuthCode(); |
||||
|
Integer expiresIn = formDTO.getExpiresIn(); |
||||
|
// 获取令牌【component_access_token】
|
||||
|
String accessToken = redisThird.getComponentAccessToken(ModuleConstant.COMPONENT_ACCESS_TOKEN); |
||||
|
// 使用授权码获取授权信息
|
||||
|
JSONObject jsonObject = new JSONObject(); |
||||
|
jsonObject.put(ModuleConstant.COMPONENT_APPID, PLATFORM_APP_ID); |
||||
|
jsonObject.put(ModuleConstant.AUTHORIZATION_CODE, authCode); |
||||
|
// String post = OkHttpHelper.post(API_QUERY_AUTH_URL + accessToken, JSON.toJSONString(jsonObject));
|
||||
|
// 重定向地址
|
||||
|
// response.sendRedirect("/wechat/authcode");
|
||||
|
} |
||||
|
} |
@ -1,59 +0,0 @@ |
|||||
package com.epmet.service.impl; |
|
||||
|
|
||||
import com.epmet.constant.ThirdPlatformConstant; |
|
||||
import com.epmet.dto.form.ThirdPlatformEventFormDTO; |
|
||||
import com.epmet.exception.AesException; |
|
||||
import com.epmet.service.DbyWechatExtService; |
|
||||
import com.epmet.constant.ModuleConstant; |
|
||||
import com.epmet.util.WXBizMsgCrypt; |
|
||||
import com.epmet.util.WXXmlToMapUtil; |
|
||||
import lombok.extern.slf4j.Slf4j; |
|
||||
import org.apache.commons.collections4.MapUtils; |
|
||||
import org.apache.commons.lang3.StringUtils; |
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
|
||||
import org.springframework.data.redis.core.RedisTemplate; |
|
||||
import org.springframework.stereotype.Service; |
|
||||
|
|
||||
import java.util.Map; |
|
||||
import java.util.concurrent.TimeUnit; |
|
||||
|
|
||||
/** |
|
||||
* @Author zxc |
|
||||
* @CreateTime 2020/7/6 9:13 |
|
||||
*/ |
|
||||
@Slf4j |
|
||||
@Service |
|
||||
public class DbyWechatExtServiceImpl implements DbyWechatExtService { |
|
||||
|
|
||||
@Autowired |
|
||||
private RedisTemplate redisTemplate; |
|
||||
|
|
||||
@Override |
|
||||
public String parseRequest(ThirdPlatformEventFormDTO formDTO) { |
|
||||
String msgSignature = formDTO.getMsgSignature(); |
|
||||
String nonce = formDTO.getNonce(); |
|
||||
String postData = formDTO.getPostData(); |
|
||||
String timeStamp = formDTO.getTimeStamp(); |
|
||||
log.info(ModuleConstant.START_RECEIVE); |
|
||||
try { |
|
||||
//这个类是微信官网提供的解密类,需要用到消息校验Token 消息加密Key和服务平台appid
|
|
||||
WXBizMsgCrypt pc = new WXBizMsgCrypt(ThirdPlatformConstant.PLATFORM_COMPONENT_TOKEN, ThirdPlatformConstant.PLATFORM_AES_KEY, ThirdPlatformConstant.PLATFORM_APP_ID); |
|
||||
String xml = pc.decryptMsg(msgSignature, timeStamp, nonce, postData); |
|
||||
// 将xml转为map
|
|
||||
Map<String, String> result = WXXmlToMapUtil.xmlToMap(xml); |
|
||||
String componentVerifyTicket = MapUtils.getString(result,ModuleConstant.TICKET_KEY); |
|
||||
if (StringUtils.isNotEmpty(componentVerifyTicket)) { |
|
||||
// 存储平台授权票据,保存ticket
|
|
||||
redisTemplate.opsForValue().set(ModuleConstant.TICKET_UNDERLINE_KEY, componentVerifyTicket, 60 * 10, TimeUnit.SECONDS); |
|
||||
String verifyTicket = redisTemplate.opsForValue().get(ModuleConstant.TICKET_UNDERLINE_KEY).toString(); |
|
||||
log.info(String.format(ModuleConstant.AUTH_TICKET,verifyTicket)); |
|
||||
} else { |
|
||||
throw new RuntimeException(ModuleConstant.ERROR_TICKET); |
|
||||
} |
|
||||
} catch (AesException e) { |
|
||||
e.printStackTrace(); |
|
||||
} |
|
||||
log.info(ModuleConstant.END_TICKET); |
|
||||
return ModuleConstant.SUCCESS; |
|
||||
} |
|
||||
} |
|
Loading…
Reference in new issue